แบบฝึกหัด: ใช้ SQLite แบบอะซิงโครนัส

เสร็จสมบูรณ์เมื่อ

แอปพลิเคชันทํางานได้ดี แต่ถ้าฐานข้อมูลมีหลายแถว UI สามารถไม่ตอบสนองได้ในขณะที่แอปดําเนินการคิวรีฐานข้อมูลและการดําเนินการอื่น ๆ ในแบบฝึกหัดนี้ คุณแปลงแอปพลิเคชันจาก SQLite API แบบซิงโครนัสเป็นเวอร์ชันอะซิงโครนัส ด้วยวิธีนี้ แอปพลิเคชันของคุณตอบสนองเสมอ ไม่ว่าคุณจะสร้างคิวรีไปยังฐานข้อมูลของคุณมากน้อยเพียงใด

สร้างการเชื่อมต่อ Async

  1. เปิดไฟล์ 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. เพิ่มคําหลัก await ลงในการเรียกใช้เมธอด Init เนื่องจาก Init ขณะนี้เป็นวิธีการ async

  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. เพิ่มคําสําคัญ await ไปยังการเรียกวิธีการ Init

  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 ใช้คําสําคัญ async และ 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. บันทึกไฟล์ MainPage.xaml.cs

  4. สร้างและเรียกใช้โปรแกรมบน Windows และ Android เพื่อตรวจสอบว่ายังคงทํางานเหมือนก่อนหน้านี้หรือไม่