Упражнение. Асинхронное использование SQLite
Приложение работает хорошо, но если база данных содержит много строк, пользовательский интерфейс может стать неответственным, пока приложение выполняет запросы к базе данных и другие операции. В этом упражнении приложение преобразуется из синхронного API SQLite в асинхронную версию. Таким образом, приложение всегда реагирует независимо от количества запросов, которые вы делаете в базе данных.
Создание асинхронного соединения
Откройте файл PersonRepository.cs в проекте People.
Измените
Init
определение метода.async
Измените тип возвращаемого значения метода наTask
.Измените свойство на
conn
кодSQLiteAsyncConnection
и обновите код в методеInit
, который инициализирует соединение.Замените вызов синхронного
CreateTable
метода асинхроннымCreateTableAsync
методом.Готовый код должен выглядеть следующим образом:
private SQLiteAsyncConnection conn; private async Task Init() { if (conn != null) return; conn = new SQLiteAsyncConnection(_dbPath); await conn.CreateTableAsync<Person>(); }
Асинхронная вставка элемента в таблицу
Измените определение
AddNewPerson
методаasync
. Измените тип возвращаемого значения метода наTask
.Добавьте ключевое
await
Init
слово в вызов метода, так какInit
теперь является методомasync
.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); } }
Асинхронное получение всех элементов из таблицы
Измените
GetAllPeople
определение метода. Это должен быть методasync
, который возвращает объектTask<List<Person>>
.Добавьте ключевое
await
Init
слово в вызов метода.Обновите этот метод, чтобы он возвращал результаты с помощью асинхронного вызова.
Код должен выглядеть следующим образом:
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>(); }
Сохраните файл PersonRepository.cs .
Тестирование асинхронной функциональности
Разверните Файл MainPage.xaml в Обозреватель решений и откройте файл MainPage.xaml.cs.
Измените оба обработчика событий нажатия кнопки, чтобы они использовали асинхронные методы из
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; }
Сохраните файл MainPage.xaml.cs .
Создайте и запустите программу в Windows и Android, убедившись, что она по-прежнему работает как раньше.