Ćwiczenie: asynchronicznie użyj sqlite

Zakończone

Aplikacja działa dobrze, ale jeśli baza danych zawiera wiele wierszy, interfejs użytkownika może nie odpowiadać, gdy aplikacja wykonuje zapytania bazy danych i inne operacje. W tym ćwiczeniu przekonwertujesz aplikację z synchronicznego interfejsu API SQLite na wersję asynchroniczną. Dzięki temu aplikacja zawsze reaguje bez względu na liczbę zapytań, które wykonujesz w bazie danych.

Tworzenie połączenia asynchronicznego

  1. Otwórz plik PersonRepository.cs w projekcie People .

  2. Zmodyfikuj definicję Init metody na async. Zmień zwracany typ metody na Task.

  3. Zmień właściwość na conn wartość i SQLiteAsyncConnection zaktualizuj kod w Init metodzie , która inicjuje połączenie.

  4. Zastąp wywołanie metody synchronicznej metodą asynchroniczną CreateTableCreateTableAsync .

    Gotowy kod powinien wyglądać następująco:

    private SQLiteAsyncConnection conn;
    
    private async Task Init()
    {
        if (conn != null)
            return;
    
        conn = new SQLiteAsyncConnection(_dbPath);
    
        await conn.CreateTableAsync<Person>();
    }
    

Wstawianie elementu do tabeli asynchronicznie

  1. Zmodyfikuj definicję metody AddNewPersonna async . Zmień zwracany typ metody na Task.

  2. await Dodaj słowo kluczowe do wywołania Init metody, ponieważ Init jest teraz async metodą.

  3. Zaktualizuj metodę , AddNewPerson aby wstawić nową Person przy użyciu asynchronicznej operacji wstawiania.

    Kod powinien wyglądać następująco:

    using System.Threading.Tasks;
    ...
    public async Task AddNewPerson(string name)
    {
       int result = 0;
       try
       {
          // Call Init()
          await Init();
    
          // basic validation to ensure a name was entered
          if (string.IsNullOrEmpty(name))
                throw new Exception("Valid name required");
    
          result = await conn.InsertAsync(new Person { Name = name });
    
          StatusMessage = string.Format("{0} record(s) added [Name: {1})", result, name);
       }
       catch (Exception ex)
       {
          StatusMessage = string.Format("Failed to add {0}. Error: {1}", name, ex.Message);
       }
    }
    

Pobieranie wszystkich elementów z tabeli asynchronicznie

  1. Zmodyfikuj definicję GetAllPeople metody. Ta metoda powinna być async i zwracać Task<List<Person>> obiekt.

  2. await Dodaj słowo kluczowe do wywołania Init metody.

  3. Zaktualizuj metodę , aby zwrócić wyniki przy użyciu wywołania asynchronicznego.

    Kod powinien wyglądać następująco:

    public async Task<List<Person>> GetAllPeople()
    {
       try
       {
          await Init();
          return await conn.Table<Person>().ToListAsync();
       }
       catch (Exception ex)
       {
          StatusMessage = string.Format("Failed to retrieve data. {0}", ex.Message);
       }
    
       return new List<Person>();
    }
    
  4. Zapisz plik PersonRepository.cs .

Testowanie funkcji asynchronicznych

  1. Rozwiń węzeł MainPage.xaml w Eksploratorze rozwiązań i otwórz plik MainPage.xaml.cs.

  2. Zmodyfikuj obie procedury obsługi zdarzeń kliknięcia przycisku, tak aby korzystały z metod asynchronicznych z PersonRepository klasy . Użyj async słów kluczowych i :await

      public async void OnNewButtonClicked(object sender, EventArgs args)
      {
         statusMessage.Text = "";
    
         await App.PersonRepo.AddNewPerson(newPerson.Text);
         statusMessage.Text = App.PersonRepo.StatusMessage;
      }
    
      public async void OnGetButtonClicked(object sender, EventArgs args)
      {
         statusMessage.Text = "";
    
         List<Person> people = await App.PersonRepo.GetAllPeople();
         peopleList.ItemsSource = people;
      }
    
  3. Zapisz plik MainPage.xaml.cs .

  4. Skompiluj i uruchom program w systemach Windows i Android, sprawdzając, czy nadal działa tak jak poprzednio.