C# - C Sharp: Toán tử await - Chờ đợi không đồng bộ để hoàn thành một tác vụ


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Toán tử await tạm dừng đánh giá phương thức async kèm theo cho đến khi thao tác không đồng bộ được biểu thị bằng toán hạng của nó hoàn tất. Khi thao tác không đồng bộ hoàn tất, toán tử await trả về kết quả của thao tác, nếu có. Khi toán tử await được áp dụng cho toán hạng đại diện cho một thao tác đã hoàn thành, nó sẽ trả về kết quả của thao tác ngay lập tức mà không cần tạm dừng phương thức kèm theo. Toán tử await không chặn chuỗi đánh giá phương thức không đồng bộ. Khi toán tử await tạm dừng phương thức async kèm theo, thì điều khiển sẽ trả về trình gọi phương thức.

Trong ví dụ sau, phương thức HttpClient.GetByteArrayAsync trả về thể hiện Task<byte[]>, đại diện cho một thao tác không đồng bộ tạo ra một mảng byte khi nó hoàn thành. Cho đến khi thao tác hoàn tất, toán tử await sẽ tạm dừng phương thức DownloadDocsMainPageAsync. Khi DownloadDocsMainPageAsync bị treo, điều khiển được trả về phương thức Main, là trình gọi của DownloadDocsMainPageAsync. Phương thức Main thực thi cho đến khi nó cần kết quả của hoạt động không đồng bộ được thực hiện bởi phương thức DownloadDocsMainPageAsync. Khi GetByteArrayAsync nhận được tất cả các byte, phần còn lại của phương thức DownloadDocsMainPageAsync sẽ được đánh giá. Sau đó, phần còn lại của phương thức Main được đánh giá.

using System;
using System.Net.Http;
using System.Threading.Tasks;

public class AwaitOperator
{
    public static async Task Main()
    {
        Task<int> downloading = DownloadDocsMainPageAsync();
        Console.WriteLine($"{nameof(Main)}: Launched downloading.");

        int bytesLoaded = await downloading;
        Console.WriteLine($"{nameof(Main)}: Downloaded {bytesLoaded} bytes.");
    }

    private static async Task<int> DownloadDocsMainPageAsync()
    {
        Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: About to start downloading.");

        var client = new HttpClient();
        byte[] content = await client.GetByteArrayAsync("https://docs.microsoft.com/en-us/");

        Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: Finished downloading.");
        return content.Length;
    }
}
// Output sẽ có dạng sau:
// DownloadDocsMainPageAsync: About to start downloading.
// Main: Launched downloading.
// DownloadDocsMainPageAsync: Finished downloading.
// Main: Downloaded 27700 bytes.

Lưu ý

Để biết phần giới thiệu về lập trình không đồng bộ, hãy xem Lập trình không đồng bộ với async và await . Lập trình không đồng bộ với asyncvà awaittuân theo mẫu không đồng bộ dựa trên nhiệm vụ .

Bạn chỉ có thể sử dụng toán tử await trong một phương thức, biểu thức lambda hoặc phương thức ẩn danh được sửa đổi bởi từ khóa async. Trong phương thức không đồng bộ, bạn không thể sử dụng toán tử await trong phần thân của hàm đồng bộ, bên trong khối của câu lệnh khóa và trong ngữ cảnh không an toàn.

Toán hạng của toán tử await thường thuộc một trong các loại .NET sau: Task, Task<TResult>, ValueTask hoặc ValueTask<TResult>. Tuy nhiên, bất kỳ biểu thức chờ đợi nào cũng có thể là toán hạng của toán tử await.

Loại biểu thức await t là TResult nếu loại biểu thức t là Task<TResult> hoặc ValueTask<TResult>. Nếu loại t là Task hoặc ValueTask thì loại await t là void. Trong cả hai trường hợp, nếu t ném ngoại lệ, thì await t ném lại ngoại lệ.

Luồng không đồng bộ và lần dùng một lần

Bạn sử dụng câu lệnh await foreach để sử dụng luồng dữ liệu không đồng bộ. Để biết thêm thông tin, hãy xem phần Câu lệnh foreach.

Bạn sử dụng câu lệnh await using để làm việc với một đối tượng dùng một lần không đồng bộ, nghĩa là một đối tượng thuộc loại triển khai giao diện IAsyncDisposable.

Toán tử await trong phương thức Main

Phương thức Main, là điểm vào của ứng dụng, có thể trả về Task hoặc Task<int>, cho phép nó không đồng bộ để bạn có thể sử dụng toán tử await trong phần thân của nó. Trong các phiên bản C# cũ hơn, để đảm bảo rằng phương thức Main chờ hoàn thành thao tác không đồng bộ, bạn có thể truy xuất giá trị của thuộc tính Task<TResult>.Result của thể hiện Task<TResult> được trả về bởi phương thức không đồng bộ tương ứng. Đối với các hoạt động không đồng bộ không tạo ra giá trị, bạn có thể gọi phương thức Task.Wait.

» Tiếp: Bảng (Table) trong WPF
« Trước: Hộp thoại (Dialog) trong C#
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!