Exercise 4: Access a SQLite database using asynchronous methods
In this exercise, you will update an existing project and modify the synchronous database calls to use their asynchronous counterparts from the SQLite.NET library.
To complete the exercise, you will need Visual Studio for Windows or macOS with the Xamarin development tools installed. You will also need either an emulator/simulator or a device to run the exercise on. Please see the setup page if you need help installing the Xamarin development environment.
Open the starter solution
This exercise is a continuation of the previous exercise. You can use your existing solution or begin from the prior Exercise 3 > Completed solution in your copy of the cloned or downloaded course materials.
Create an Async connection
- Open the PersonRepository.cs file in the People PCL project.
- Change the
SQLiteConnectionconn property to aSQLiteAsyncConnection. This requires updating the property and the instantiation. - In the constructor, notice the call to
CreateTableis no longer valid. Replace this call withCreateTableAsync. CreateTableAsyncis aTask-returning async method. Use theWait()method on the returnedTaskto make this a blocking call to ensure the table is created before the constructor completes. Note that we are using this blocking call to keep the exercise as simple as possible. In general you should not mix asynchronous and synchronous code as there are scenarios where it can cause an application to deadlock.
private SQLiteAsyncConnection conn;
public PersonRepository (string dbPath)
{
conn = new SQLiteAsyncConnection(dbPath);
conn.CreateTableAsync<Person>().Wait();
}
Use async database calls
-
Modify the
AddNewPersonmethod to insert a newPersonusing an asynchronous call:- Refactor the method to use
async/await. - Change the return type to be a
Taskso we can see exceptions that might happen in the method from the caller. - You will need a new namespace:
System.Threading.Tasksto return aTasktype. - Rename the method to append the term Async to the end of the method name.
- Refactor the method to use
using System.Threading.Tasks;
...
public async Task AddNewPersonAsync(string name)
{
int result = 0;
try
{
//basic validation to ensure a name was entered
if (string.IsNullOrEmpty(name))
throw new Exception("Valid name required");
// TODO: insert a new person into the Person table
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);
}
}
-
Modify the
GetAllPeoplemethod to return the results using an asynchronous call.- Refactor the method to use
async/awaitandToListAsyncto perform theSELECTquery. - Rename the method to append the term Async to the end of the method name.
- The returning result from the method will need to be modified to return a
Task<List<Person>>.
- Refactor the method to use
public async Task<List<Person>> GetAllPeopleAsync()
{
try
{
return await conn.Table<Person>().ToListAsync();
}
catch (Exception ex)
{
StatusMessage = string.Format("Failed to retrieve data. {0}", ex.Message);
}
return new List<Person>();
}
- In the MainPage.xaml.cs file, modify both of the
Button.Clickevent handlers to use the async methods from thePersonRepositoryclass, making use of theasyncandawaitkeywords.
public async void OnNewButtonClicked(object sender, EventArgs args)
{
statusMessage.Text = string.Empty;
await App.PersonRepo.AddNewPersonAsync(newPerson.Text);
statusMessage.Text = PersonRepository.Instance.StatusMessage;
}
public async void OnGetButtonClicked(object sender, EventArgs args)
{
statusMessage.Text = string.Empty;
var people = await App.PersonRepo.GetAllPeopleAsync();
peopleList.ItemsSource = people;
}
- Build the solution and run the app to verify it still builds and functions correctly.
Exercise summary
In this exercise, we refactored our existing project to utilize the asynchronous versions of the SQLite.NET methods so that our UI thread is not tied up when I/O is being performed.
If you have time, try adding some filters into the query, adding support to edit records and delete records through new buttons in the UI.
You can view the completed solution in the Exercise 4 > Completed folder of your copy of the cloned or downloaded course materials.