我正在关注MSDN上的await教程,我正在尝试找出使用await
作为语句与使用{{1}之间的区别作为表达式。整个异步等待的事情让我大吃一惊,我找不到这个特例的任何例子。
基本上,我想看看如何异步使用多个await
,这意味着我不想在第二个开始之前等待第一个完成。对我来说,这一开始就违背了异步的目的:
await
但是,通过微妙的更改,两个“完成”的总计只需要3秒钟,这就是我想要的 - 两个private async void button1_Click(object sender, EventArgs e)
{
// Using await as an expression
string result_a = await WaitAsynchronouslyAsync();
string result_b = await WaitAsynchronouslyAsync();
// This takes six seconds to appear
textBox1.Text = result_a + Environment.NewLine;
textBox1.Text += result_b;
}
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(3000);
return "Finished";
}
真正异步运行:
await
我的问题是,为什么这些行为有所不同?我在这里错过了什么微妙的一点?
答案 0 :(得分:11)
首先,您需要区分 parallelism 和 asynchrony 。在第一种情况下,它可能仍然值得同步执行操作(实际上第二个操作可能取决于第一个操作的结果)以释放UI线程等。
但至于为什么他们的行为不同 - await
只是一个表达式。它是一种可以作为语句出现的表达式,但它的行为方式相同,就像调用返回字符串的方法一样,但忽略了返回值。您可以通过将第一个代码更改为:
// Still takes 6 seconds...
var a = WaitAsynchronouslyAsync();
await a;
var b = WaitAsynchronouslyAsync();
await b;
那还需要6秒钟。关键是你只是在等待第一个完成后才开始第二个异步操作。在第二个示例中,两个异步操作同时发生。
您仍然可以和将值分配给变量,您只需要记住等待:
// This will only take 3 seconds
var a = WaitAsynchronouslyAsync();
var b = WaitAsynchronouslyAsync();
string result_a = await a;
string result_b = await b;
所以基本上,差别与语句/表达无关 - 它与序列是start / await / start / await还是start / start / await / await有关。
答案 1 :(得分:4)
在这两种情况下,await关键字都会引入异步。您看到差异的原因是,在案例1中,您按顺序启动两个任务,在案例2中,您让它们并行运行。
也许对这两种情况的逐步解释清除了事情
string result_a = await WaitAsynchronouslyAsync();
string result_b = await WaitAsynchronouslyAsync();
这里发生的是:
在第二种情况下:
var a = WaitAsynchronouslyAsync();
var b = WaitAsynchronouslyAsync();
await a;
await b;