await(C# 参考)

await 运算符应用于一个异步方法的任务挂起方法的执行,直到等待任务完成。 任务表示正在进行的工作。

await 使用的异步方法必须被 异步 关键字修改。 这样,方法是使用 async 修饰符和通常包含一个或多 await 表达式,引用 异步方法。

备注

async 和 await 关键字在 Visual Studio 2012 中引入)。有关在该版本的新增功能的信息,请参见 Visual Studio 2012 中的新增功能

有关异步编程的介绍,请参见 使用 Async 和 Await 的异步编程(C# 和 Visual Basic)

await 运算符通常将应用的任务是从调用的返回值设置为实现的 基于任务的异步模式方法。 示例包括类型 TaskTask<TResult>的值。

在下面的代码中,HttpClient 方法 GetByteArrayAsync 返回 Task<byte[]>,getContentsTask。 当任务完成,任务是承诺生成实际字节数组。 await 运算符在 SumPageSizesAsync 会应用于 getContentsTask 挂起执行,直到 getContentsTask 完成。 同时,控件返回到 SumPageSizesAsync的调用方。 当 getContentsTask 完成时,await 表达式计算为字节数组。

private async Task SumPageSizesAsync()
{
    // To use the HttpClient type in desktop apps, you must include a using directive and add a 
    // reference for the System.Net.Http namespace.
    HttpClient client = new HttpClient();
    // . . .
    Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
    byte[] urlContents = await getContentsTask;

    // Equivalently, now that you see how it works, you can write the same thing in a single line.
    //byte[] urlContents = await client.GetByteArrayAsync(url);
    // . . .
}

重要

有关完整的示例,请参见演练:使用 Async 和 Await 访问 Web(C# 和 Visual Basic)。您可以从 开发人员代码示例 Microsoft 网站上的示例。此示例在 AsyncWalkthrough_HttpClient 项目。

由返回 Task<TResult>前面的示例所示,因此,如果 await 应用于方法的结果调用,然后 await 表达式的类型为 TResult。 如果 await 应用于返回 Task方法的结果调用,则 await 表达式的类型无效。 下面的示例演示差异。

// Keyword await used with a method that returns a Task<TResult>.
TResult result = await AsyncMethodThatReturnsTaskTResult();

// Keyword await used with a method that returns a Task.
await AsyncMethodThatReturnsTask();

await 表达式不阻止它在其上执行的线程。 相反,它导致编译器注册异步方法的其余部分为等待的任务继续。 然后控件回异步方法的调用方。 当任务完成时,将会调用其延续任务,并且,异步方法的执行恢复它将会停止的位置。

await 表达式。async 修饰符指示一个直接封闭方法、lambda 表达式或匿名方法的主体只能发生。 这个术语 等待 作为一个仅关键字在该上下文。 在其他地方,则将该说明符解释为标识符。 在方法、lambda 表达式或匿名方法内,await 表达式对象处于同步函数体不会发生,在查询表达式中,若 catch 或 finally 块 异常处理语句,在 lock 语句块,或者在 不安全 上下文。

异常

大多数异步方法返回 TaskTask<TResult>。 返回的任务的属性传播有关其状态和历史记录的信息,例如任务是否已完成,异步方法是否引发异常或已取消,以及最终结果是。 await 运算符访问这些属性。

如果等待导致异常的一个任务返回的异步方法,await 运算符再次引发异常。

如果等待取消的一个任务返回的异步方法,await 运算符再次引发 OperationCanceledException

在出错状态的单一任务可能反映出多个异常。 例如,任务可能为调用的结果。Task.WhenAll。 当您等待此类任务,异常的等待操作再次引发只有一个。 但是,您无法预测哪些异常来重新引发。

在中的错误处理异步方法的示例,请参见 try-catch(C# 参考)

示例

以下 windows 窗体示例阐释如何在异步方法的 await,WaitAsynchronouslyAsync。 对比度该方法的行为与 WaitSynchronously行为。 不 await 运算符应用于任务,WaitSynchronously 尽管使用在定义的 async 修饰符和调用同步运行对其主体的 Thread.Sleep

private async void button1_Click(object sender, EventArgs e)
{
    // Call the method that runs asynchronously.
    string result = await WaitAsynchronouslyAsync();

    // Call the method that runs synchronously.
    //string result = await WaitSynchronously ();

    // Display the result.
    textBox1.Text += result;
}

// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window 
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
    await Task.Delay(10000);
    return "Finished";
}

// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
    // Add a using directive for System.Threading.
    Thread.Sleep(10000);
    return "Finished";
}

请参见

任务

演练:使用 Async 和 Await 访问 Web(C# 和 Visual Basic)

参考

async(C# 参考)

概念

使用 Async 和 Await 的异步编程(C# 和 Visual Basic)