Упражнение. Асинхронное использование SQLite

Завершено

Приложение работает хорошо, но если база данных содержит много строк, пользовательский интерфейс может стать неответственным, пока приложение выполняет запросы к базе данных и другие операции. В этом упражнении приложение преобразуется из синхронного API SQLite в асинхронную версию. Таким образом, приложение всегда реагирует независимо от количества запросов, которые вы делаете в базе данных.

Создание асинхронного соединения

  1. Откройте файл PersonRepository.cs в проекте People.

  2. Измените Init определение метода.async Измените тип возвращаемого значения метода на Task.

  3. Измените свойство на conn код SQLiteAsyncConnection и обновите код в методе Init , который инициализирует соединение.

  4. Замените вызов синхронного CreateTable метода асинхронным CreateTableAsync методом.

    Готовый код должен выглядеть следующим образом:

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

Асинхронная вставка элемента в таблицу

  1. Измените определение AddNewPerson метода async. Измените тип возвращаемого значения метода на Task.

  2. Добавьте ключевое await Init слово в вызов метода, так как Init теперь является методом async .

  3. AddNewPerson Обновите метод для вставки нового Person с помощью асинхронной операции вставки.

    Код должен выглядеть следующим образом:

    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);
       }
    }
    

Асинхронное получение всех элементов из таблицы

  1. Измените GetAllPeople определение метода. Это должен быть метод async, который возвращает объект Task<List<Person>>.

  2. Добавьте ключевое await Init слово в вызов метода.

  3. Обновите этот метод, чтобы он возвращал результаты с помощью асинхронного вызова.

    Код должен выглядеть следующим образом:

    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. Сохраните файл PersonRepository.cs .

Тестирование асинхронной функциональности

  1. Разверните Файл MainPage.xaml в Обозреватель решений и откройте файл MainPage.xaml.cs.

  2. Измените оба обработчика событий нажатия кнопки, чтобы они использовали асинхронные методы из PersonRepository класса. Используйте ключевые слова async и 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. Сохраните файл MainPage.xaml.cs .

  4. Создайте и запустите программу в Windows и Android, убедившись, что она по-прежнему работает как раньше.