#unity/日常积累

await 运算符 - 异步等待任务完成

await 运算符暂停对其所属的 async 方法的求值,直到其操作数表示的异步操作完成。 异步操作完成后,await 运算符将返回操作的结果(如果有)。 当 await 运算符应用到表示已完成操作的操作数时,它将立即返回操作的结果,而不会暂停其所属的方法。 await 运算符不会阻止计算异步方法的线程。 当 await 运算符暂停其所属的异步方法时,控件将返回到方法的调用方。

在下面的示例中,HttpClient.GetByteArrayAsync 方法返回 Task<byte[]> 实例,该实例表示在完成时生成字节数组的异步操作。 在操作完成之前,await 运算符将暂停 DownloadDocsMainPageAsync 方法。 当 DownloadDocsMainPageAsync 暂停时,控件将返回到 Main 方法,该方法是 DownloadDocsMainPageAsync 的调用方。 Main 方法将执行,直至它需要 DownloadDocsMainPageAsync 方法执行的异步操作的结果。 当 GetByteArrayAsync 获取所有字节时,将计算 DownloadDocsMainPageAsync 方法的其余部分。 之后,将计算 Main 方法的其余部分。

 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
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://learn.microsoft.com/en-us/");

        Console.WriteLine($"{nameof(DownloadDocsMainPageAsync)}: Finished downloading.");
        return content.Length;
    }
}
// Output similar to:
// DownloadDocsMainPageAsync: About to start downloading.
// Main: Launched downloading.
// DownloadDocsMainPageAsync: Finished downloading.
// Main: Downloaded 27700 bytes.

必须提供 await 表达式的操作数,才能在任务完成时进行通知。 通常,任务完成时(无论成功还是失败)都会调用委托。 C# 语言规范的 await 部分提供了有关如何实现这些通知的详细信息。

前一个示例使用异步 Main 方法。 有关详细信息,请参阅 Main 方法中的 await 运算符部分。