Ejercicio: Uso de SQLite de forma asincrónica

Completado

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

  1. Abra el archivo PersonRepository.cs del proyecto People.

  2. Modifique la definición del método Init para que sea async. Cambie el tipo de valor devuelto del método a Task.

  3. Cambie la propiedad conn a un SQLiteAsyncConnection y actualice el código en el método Init que inicializa la conexión.

  4. Reemplace la llamada al método sincrónico CreateTable por el método asincrónico CreateTableAsync.

    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

  1. Modifique la definición del método AddNewPerson para que sea async. Cambie el tipo de valor devuelto del método a Task.

  2. Agregue la palabra clave await a la llamada de método Init, porque Init ahora es un método async.

  3. Actualice el método AddNewPerson para insertar un nuevo elemento Person 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

  1. Modifique la definición del método GetAllPeople. Este método debe ser async y devolver un objeto Task<List<Person>>.

  2. Agregue la palabra clave await a la llamada de método Init.

  3. 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>();
    }
    
  4. Guarde el archivo PersonRepository.cs.

Prueba de la función asincrónica

  1. Expanda MainPage.xaml en el Explorador de soluciones y abra el archivo MainPage.xaml.cs.

  2. 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 clave async y 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;
      }
    
  3. Guarde el archivo MainPage.xaml.cs.

  4. Compile y ejecute el programa en Windows y Android, comprobando que sigue funcionando como antes.