等待声明与表达

Jef*_*f E 5 c# async-await

我跟随的await在MSDN教程中,我试图找出两者的区别:await作为声明与使用await作为一种表达.整个异步等待的事情让我大吃一惊,我找不到这个特例的任何例子.

基本上,我想看看如何await异步使用多个s,这意味着我不想在第二个开始之前等待第一个完成.对我来说,这打破了异步的目的:

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";
}
Run Code Online (Sandbox Code Playgroud)

然而,通过微妙的改变,两个"完成"的出现只需要3秒,这就是我想要的 - 两个await真正异步运行:

private async void button1_Click(object sender, EventArgs e)
{
    var a = WaitAsynchronouslyAsync();
    var b = WaitAsynchronouslyAsync();

    // Using await as a statement
    await a;
    await b;

    // This takes three seconds to appear
    textBox1.Text = a.Result + Environment.NewLine;
    textBox1.Text += b.Result;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么这些行为有所不同?我在这里错过了什么微妙的观点?

Jon*_*eet 11

首先,您需要区分并行性异步性.在第一种情况下,它可能仍然值得同步执行操作(实际上第二个操作可能取决于第一个操作的结果)以释放UI线程等.

至于为什么他们不同的表现- await唯一的一种表达.它是一种可以作为语句出现的表达式,但它的行为方式相同,就像调用返回字符串的方法一样,但忽略了返回值.您可以通过将第一个代码更改为:

// Still takes 6 seconds...
var a = WaitAsynchronouslyAsync();
await a;

var b = WaitAsynchronouslyAsync();
await b;
Run Code Online (Sandbox Code Playgroud)

那还需要6秒钟.关键是你在等待第一个异步操作完成后才开始第二个异步操作.在第二个示例中,两个异步操作同时发生.

你仍然可以这样做并将值赋给变量,你只需要记住等待:

// This will only take 3 seconds
var a = WaitAsynchronouslyAsync();
var b = WaitAsynchronouslyAsync();
string result_a = await a;
string result_b = await b;
Run Code Online (Sandbox Code Playgroud)

所以基本上,差别不在于语句/表达式 - 它与序列是start/await/start/await还是start/start/await/await有关.