.NET Async/Await: Async trên UI thread

Từ khi Microsoft giới thiệu cách tiếp cận async/await cho lập trình bất đồng bộ (Asynchronous Programming) trong .NET 4.5, thì việc code cho các method bất đồng bộ (async) đỡ hơn rất nhiều.

Và bạn có thể dễ dàng thấy trong các tutorial về async luôn có example kiểu như:

(Code WPF)

Và bạn tưởng thế là xong, hàm sẽ chạy async là ko phải lo về vấn đề treo thead nữa, quá khỏe.

Nhưng vấn đề không đơn giản như thế.
Bây giờ bạn thử bỏ trong hàm AnMethodAsync() đoạn code sau:

Run đoạn code trên và khi bạn nhấn button1, thì UI sẽ treo cứng ngắc trong 5s.
Thế quái nào nhỉ, mình đã apply async/await đàng hoàng rồi mà UI vẫn treo.
Sau một hồi ngâm cứu mới hiểu ra vấn đề: Trong hàm AnMethodAsync không hề tạo ra bất kỳ một task nào trên thread khác. Hậu quả là dù có asyn đi nữa nhưng nó vẫn chạy trên UI thread -> treo UI.

Nếu bạn làm trên Xamarin thì bạn cũng gặp tình trạng tương tự:

(Code Xamarin.Android)

Thế thì fix bằng cách nào, có 2 cách:

Cách 1: Tạo mới một task và đoạn thực thi vào:

Cách 2: Dùng Task.Delay() thay vì Thread.Sleep()

Vậy câu hỏi đặt ra là : Lỡ mình dùng các thư viện ngoài như : Http, Encrypt, Image,… mà có các hàm async mà chạy trên UI thì có cần tạo một Task mới và bỏ hàm đó vào không.
Câu trả lời là không, vì hầu hết các thư viện .NET có dùng async sẽ tạo Task trên thread khác, đây là cách làm chung của mọi thư viện nên bạn không cần phải lo về điều này. Trừ khi người viết thư viện đó là mình :D.

Thực ra còn một cách nữa là dùng ConfigureAwait() cho Task nhưng sẽ phát sinh vấn đề nhỏ, mình sẽ đề cập ở bài tiếp theo.

Link tham khảo: https://codingjourneyman.com/2015/10/05/async-await-and-the-ui-thread/

Spread the love
  •  
  •  
  •  
  •  
  •  

Leave a Reply

5 Comments on ".NET Async/Await: Async trên UI thread"

Notify of
avatar
Sort by:   newest | oldest | most voted
Khoa Nguyen Van
Guest

ConfigureAwait thì sao hả bác? Bác nói rõ được không?

Khoa Nguyen Van
Guest
Khoa Minhy
Guest
Khoa Minhy
Guest
Nguoi Tuyen Hanfg
Guest