Ejercicio: Uso de SQLite de forma asincrónica
La aplicación funciona bien, pero si la base de datos contiene muchas filas, la interfaz de usuario puede dejar de responder mientras la aplicación realiza consultas de base de datos y otras operaciones. En este ejercicio, convertirá la aplicación de la API de SQLite sincrónica a la versión asincrónica. De este modo, la aplicación siempre responde independientemente del número de consultas que realice en la base de datos.
Creación de una conexión asincrónica
Abra el archivo PersonRepository.cs del proyecto People.
Modifique la definición del método
Init
para que seaasync
. Cambie el tipo de valor devuelto del método aTask
.Cambie la propiedad
conn
a unSQLiteAsyncConnection
y actualice el código en el métodoInit
que inicializa la conexión.Reemplace la llamada al método sincrónico
CreateTable
por el método asincrónicoCreateTableAsync
.Este es el aspecto que debería tener el código completado:
private SQLiteAsyncConnection conn; private async Task Init() { if (conn != null) return; conn = new SQLiteAsyncConnection(_dbPath); await conn.CreateTableAsync<Person>(); }
Inserción de un elemento en una tabla de forma asincrónica
Modifique la definición del método
AddNewPerson
para que seaasync
. Cambie el tipo de valor devuelto del método aTask
.Agregue la palabra clave
await
a la llamada de métodoInit
, porqueInit
ahora es un métodoasync
.Actualice el método
AddNewPerson
para insertar un nuevo elementoPerson
mediante una operación de inserción asincrónica.El código debe ser similar al siguiente:
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); } }
Obtención de todos los elementos de una tabla de forma asincrónica
Modifique la definición del método
GetAllPeople
. Este método debe serasync
y devolver un objetoTask<List<Person>>
.Agregue la palabra clave
await
a la llamada de métodoInit
.Actualice el método para que devuelva los resultados mediante una llamada asincrónica.
El código debe ser similar al siguiente:
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>(); }
Guarde el archivo PersonRepository.cs.
Prueba de la función asincrónica
Expanda MainPage.xaml en el Explorador de soluciones y abra el archivo MainPage.xaml.cs.
Modifique ambos controladores de eventos de clic con botón para que usen los métodos asincrónicos de la clase
PersonRepository
. Use las palabras claveasync
yawait
: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; }
Guarde el archivo MainPage.xaml.cs.
Compile y ejecute el programa en Windows y Android, comprobando que sigue funcionando como antes.