演習: SQLite を非同期で使用する
アプリケーションは正しく機能しています。しかし、データベースに多くの行が含まれている場合、アプリでデータベース クエリやその他の操作が実行されている間は UI が応答しなくなることがあります。 この演習では、アプリケーションを同期型の SQLite API から非同期型に変換します。 そうすることで、データベースに対して行ったクエリの数に関係なく、アプリケーションで常に応答できるようになります。
非同期接続の作成
People プロジェクト内の PersonRepository.cs ファイルを開きます。
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
に変更します。Init
がasync
メソッドになったため、await
キーワードをInit
メソッド呼び出しに追加します。非同期挿入操作を使用して、新しい
Person
を挿入するようにAddNewPerson
メソッドを更新します。コードは、次のようになります。
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>>
オブジェクトを返す必要があります。Init
メソッド呼び出しにawait
キーワードを追加します。非同期呼び出しを使用して結果を返すようにメソッドを更新します。
コードは、次のようになります。
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 でプログラムをビルドして実行し、以前と同様に機能することを確認します。