练习:异步使用 SQLite

已完成

应用程序运行良好,但如果数据库包含许多行,则当应用执行数据库查询和其他操作时,UI 可能无响应。 在本练习中,你会将应用程序从同步的 SQLite API 转换为异步版本。 这样一来,无论对数据库执行多少次查询,应用程序将始终能够保持响应。

创建异步连接

  1. 打开“People”项目中的“PersonRepository.cs”文件

  2. Init 方法的定义修改为 async。 将此方法的返回类型更改为 Task

  3. conn 属性更改为 SQLiteAsyncConnection 并更新初始化连接的 Init 方法中的代码。

  4. 将对同步 CreateTable 方法的调用替换为异步 CreateTableAsync 方法。

    完成的代码应如下所示:

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

以异步方式向表中插入项

  1. AddNewPerson 方法的定义修改为 async。 将此方法的返回类型更改为 Task

  2. Init 方法调用中添加 await 关键字,因为 Init 现在是 Init 方法。

  3. 更新 AddNewPerson 方法,以使用异步插入操作插入新的 Person

    代码应如下所示:

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

异步获取表中的所有项

  1. 修改 GetAllPeople 方法定义。 此方法应为 async 并返回对象 Task<List<Person>>

  2. Init 方法调用中添加 await 关键字。

  3. 更新此方法,以使用异步调用返回结果。

    代码应如下所示:

    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. 保存 PersonRepository.cs 文件

测试异步功能

  1. 在解决方案资源管理器中展开 MainPage.xaml 节点并打开 MainPage.xaml.cs 文件

  2. 修改两个单击按钮事件处理程序以使用 PersonRepository 类中的异步方法。 使用关键字 asyncawait

      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. 保存 MainPage.xaml.cs 文件

  4. 在 Windows 和 Android 上构建并运行该程序,以验证它是否仍能像以前一样正常运行。