Các từ khóa await / async trong C#
Ngày cập nhật: 18/09/2018 | Số lần xem: 20.217 | Phân loại: CSharp
Tìm kiếm
Trong các phương thức được đánh dấu bằng async, từ khóa await
đóng vai trò rất quan trọng. Khi một luồng chính gọi vào một phương thức async và gặp phải từ khóa await
, nó sẽ tự động tạm dừng việc thực hiện phương thức đó, không làm tắc nghẽn các công việc khác đang chạy. Thay vào đó, luồng chính có thể tiếp tục xử lý những tác vụ khác trong khi chờ đợi kết quả từ thao tác bất đồng bộ.
Ví dụ, ta có thể thực hiện yêu cầu HTTP bất đồng bộ khi người dùng nhấn nút:
|
|
Khi nhấn vào nút, chương trình sẽ gửi yêu cầu đến URL mà không làm chậm giao diện hoặc các chức năng khác của ứng dụng. Việc sử dụng async
và await
giúp chúng ta viết mã dễ hiểu và dễ bảo trì hơn rất nhiều so với lập trình đa luồng truyền thống.
Sự khác biệt giữa await và tạo luồng mới (thread)
So với cách lập trình đa luồng truyền thống, việc sử dụng async
và await
đơn giản hơn rất nhiều. Bạn không cần quản lý trực tiếp các luồng hay lo lắng về việc đồng bộ hóa dữ liệu giữa các luồng. Điều này giúp giảm thiểu rủi ro lỗi như deadlock hay race condition.
Đặc biệt, tính bất đồng bộ lại cực kỳ hữu ích đối với các ứng dụng liên quan đến giao diện người dùng (UI), vì toàn bộ hoạt động UI thường chỉ chạy trên một luồng duy nhất. Trong một ứng dụng đồng bộ, nếu một quá trình bị chặn, tất cả các quá trình khác cũng đều bị đình trệ. Lúc đó, người dùng có thể nghĩ rằng ứng dụng đã bị treo, trong khi thực tế là nó đang đợi một phản hồi nào đó.
Những điều cần lưu ý khi định nghĩa hàm async
Một hàm async cần tuân theo một số quy tắc nhất định để đảm bảo hoạt động đúng đắn:
|
|
Làm thế nào để biết một API hỗ trợ async?
Các phương thức hỗ trợ lập trình bất đồng bộ thường có đặc điểm chung như sau:
- Tên phương thức có hậu tố “Async”, ví dụ:
GetAsStringAsync
,ReadAsync
,WriteAsync
. - Kiểu trả về là
Task
hoặcTask<T>
.
Có thể bạn đang thắc mắc rằng mình sẽ tìm đâu ra các phương thức như
GetStringAsync
để sử dụng trong lập trình async. Từ phiên bản .NET Framework 4.5 trở lên và .NET Core, rất nhiều thành viên trong thư viện hệ thống đã hỗ trợ async và await. Bạn có thể nhận biết chúng qua hậu tố “Async” trong tên phương thức và kiểu trả về làTask
hoặcTask<T>
. Ví dụ, lớpSystem.IO.Stream
có các phương thức nhưCopyToAsync
,ReadAsync
, vàWriteAsync
song hành cùng các phương thức đồng bộCopyTo
,Read
, vàWrite
.
Lỗi: “Task MainPage.Button_Click_Async(object, RoutedEventArgs)’ has the wrong return type”
Dưới đây là đoạn mã gây lỗi:
|
|
Sửa lại thành:
|
|
Sau khi sửa, chương trình sẽ biên dịch thành công.
Lý do: Chỉ khi bạn tạo một hàm async cần được await bởi hàm khác, thì bạn mới nên sử dụng Task
làm kiểu trả về. Trong trường hợp của sự kiện click nút – nơi không cần được await bởi ai – việc sử dụng void
là phù hợp và hợp lệ.