Exercise: Use SQLite asynchronously
The application works well, but if the database contains many rows, the UI can become unresponsive while the app performs database queries and other operations. In this exercise, you convert the application from the synchronous SQLite API to the asynchronous version. This way, your application is always responsive no matter how many queries you make to your database.
Create an Async connection
Open the PersonRepository.cs file in the People project.
Modify the
Initmethod's definition to beasync. Change the return type of the method toTask.Change the
connproperty to aSQLiteAsyncConnectionand update the code in theInitmethod that initializes the connection.Replace the call to the synchronous
CreateTablemethod with the asynchronousCreateTableAsyncmethod.The completed code should look like this:
private SQLiteAsyncConnection conn; private async Task Init() { if (conn != null) return; conn = new SQLiteAsyncConnection(_dbPath); await conn.CreateTableAsync<Person>(); }
Insert an item into a table asynchronously
Modify the definition of the
AddNewPersonmethod to beasync. Change the return type of the method toTask.Add the
awaitkeyword to theInitmethod call becauseInitis now anasyncmethod.Update the
AddNewPersonmethod to insert a newPersonby using an asynchronous insert operation.The code should look like this:
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); } }
Get all items from a table asynchronously
Modify the
GetAllPeoplemethod definition. This method should beasyncand return aTask<List<Person>>object.Add the
awaitkeyword to theInitmethod call.Update the method to return the results by using an asynchronous call.
The code should look like this:
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>(); }Save the PersonRepository.cs file.
Test the asynchronous functionality
Expand MainPage.xaml in the Solution Explorer and open the MainPage.xaml.cs file.
Modify both of the button-click event handlers so that they use the asynchronous methods from the
PersonRepositoryclass. Make use of theasyncandawaitkeywords: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; }Save the MainPage.xaml.cs file.
Build and run the program on Windows and Android, verifying that it still functions as before.