Exercício: Use o SQLite de forma assíncrona

Concluído

O aplicativo funciona bem, mas se o banco de dados contiver muitas linhas, a interface do usuário pode deixar de responder enquanto o aplicativo executa consultas de banco de dados e outras operações. Neste exercício, você converte o aplicativo da API SQLite síncrona para a versão assíncrona. Dessa forma, seu aplicativo é sempre responsivo, não importa quantas consultas você faça ao seu banco de dados.

Criar uma conexão assíncrona

  1. Abra o arquivo PersonRepository.cs no projeto Pessoas .

  2. Modifique a Init definição do método para ser async. Altere o tipo de retorno do método para Task.

  3. Altere a conn propriedade para a SQLiteAsyncConnection e atualize o Init código no método que inicializa a conexão.

  4. Substitua a chamada para o método síncrono CreateTable pelo método assíncrono CreateTableAsync .

    O código completo deverá ter o seguinte aspeto:

    private SQLiteAsyncConnection conn;
    
    private async Task Init()
    {
        if (conn != null)
            return;
    
        conn = new SQLiteAsyncConnection(_dbPath);
    
        await conn.CreateTableAsync<Person>();
    }
    

Inserir um item numa tabela de forma assíncrona

  1. Modifique a AddNewPerson definição do método a ser async. Altere o tipo de retorno do método para Task.

  2. Adicione a await palavra-chave à chamada de Init método porque Init agora é um async método.

  3. Atualize o método para inserir um novo AddNewPerson usando uma operação de inserção assíncronaPerson.

    O código deve ter esta aparência:

    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);
       }
    }
    

Obter todos os itens de uma tabela de forma assíncrona

  1. Modifique a definição do GetAllPeople método. Este método deve ser async e retornar um Task<List<Person>> objeto.

  2. Adicione a await palavra-chave à chamada de Init método.

  3. Atualize o método para retornar os resultados usando uma chamada assíncrona.

    O código deve ter esta aparência:

    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. Salve o arquivo PersonRepository.cs .

Testar a funcionalidade assíncrona

  1. Expanda MainPage.xaml no Gerenciador de Soluções e abra o arquivo MainPage.xaml.cs .

  2. Modifique ambos os manipuladores de eventos button-click para que eles usem os métodos assíncronos PersonRepository da classe. Faça uso das async palavras-chave e 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. Salve o arquivo MainPage.xaml.cs .

  4. Compile e execute o programa no Windows e Android, verificando se ele ainda funciona como antes.