Giới thiệu về từ khóa await

Giới thiệu về từ khóa await

game tang 100k trai nghiem,cách xem đá gà thomo trực tiếp,tải game 789 club apk

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:

1
2
3
4
5
6
7
private async void Button_Click_Async(object sender, RoutedEventArgs e)
{ 
    var client = new HttpClient(); 
    var uri = new Uri(Uri.EscapeUriString(url));
    byte[] urlContents = await client.GetByteArrayAsync(uri);
    Console.WriteLine($"{url}: {urlContents.Length/2:N0} ký 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 asyncawait 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 asyncawait đơ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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Ba điều cần chú ý trong phần khai báo:
// - Phương thức có từ khóa async.
// - Kiểu trả về là Task hoặc Task<T>. (Xem thêm phần "Kiểu trả về")
//   Trong ví dụ này, kiểu trả về là Task<int> vì lệnh return trả về một số nguyên.
// - Tên phương thức nên kết thúc bằng hậu tố "Async".
async Task<int> AccessTheWebAsync() 
{  
    // Cần thêm tham chiếu System.Net.Http để khai báo HttpClient.
    HttpClient client = new HttpClient(); 

    // GetStringAsync trả về một Task<string>. Khi await task này, bạn sẽ nhận được chuỗi (urlContents).
    Task<string> getStringTask = client.GetStringAsync(" 

    // Bạn có thể thực hiện các công việc độc lập ở đây trước khi await.
    DoIndependentWork(); 

    // Toán tử await tạm dừng phương thức AccessTheWebAsync.
    // - Phương thức không thể tiếp tục cho đến khi getStringTask hoàn thành.
    // - Trong thời gian đó, quyền kiểm soát được trả lại cho người gọi phương thức.
    // - Khi getStringTask hoàn tất, quyền kiểm soát quay trở lại tại vị trí await.
    // - Toán tử await sau đó lấy giá trị chuỗi từ getStringTask.
    string urlContents = await getStringTask; 

    // Lệnh return xác định kết quả là một số nguyên.
    // Các phương thức đang await AccessTheWebAsync sẽ nhận được giá trị chiều dài chuỗi.
    return urlContents.Length; 
}

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ặc Task<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ặc Task<T>. Ví dụ, lớp System.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:

1
private async Task Button_Click_Async(object sender, RoutedEventArgs e)

Sửa lại thành:

1
private async void Button_Click_Async(object sender, RoutedEventArgs e)

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ệ.

comments powered by Disqus
Built with Hugo
Theme Stack thiết kế bởi Jimmy