" await / async":为什么2段代码不运行?

时间:2013-03-31 16:03:44

标签: c# asynchronous task-parallel-library async-await c#-5.0

这是一个简单的WinForm应用程序来试验await / async关键字。下面是按钮的事件处理程序。

我快速点击按钮两次,间隔小于3000毫秒,因此背景线程尚未完成。

    private Task<String> f()
    {
        return Task.Run<String>(() =>
            {
                Thread.Sleep(3000);
                return Thread.CurrentThread.ManagedThreadId.ToString();
            }
        );
    }

    private async void async_btn_Click(object sender, EventArgs e)
    {
        Task<String> wait_task = f();

        //Code 1, this outputs first 3, and then 3 is REPLACED with 4.
        //this.async_lbl.Text += await wait_task;  //3 -> 4

        //Code 2, this outputs first 3, and then 34.
        //String wait_value = await wait_task;
        //this.async_lbl.Text += wait_value;  //3 -> 34
    }

为什么1和2的输出不同?

谢谢!

ADD

以下是反映的代码:

3 - &gt; 34

// WindowsFormsApplication1.Form1
private async void async_btn_Click(object sender, EventArgs e)
{
    Task<string> task = this.f();
    string str = await task;
    Label expr_AA = this.async_lbl;
    expr_AA.Text += str;
}

3 - &gt; 4

// WindowsFormsApplication1.Form1
private async void async_btn_Click(object sender, EventArgs e)
{
    Task<string> task = this.f();
    Label label = this.async_lbl;
    label.Text += await task;
}

1 个答案:

答案 0 :(得分:11)

这在C#语言规范中有解释。 Section 14.3.2: Compound Assignment

  

[T]他的操作被评估为x = x op y,除了x只被评估一次。

该行

this.async_lbl.Text += await wait_task;

扩展为

this.async_lbl.Text = this.async_lbl.Text + await wait_task;

执行该行时,this.async_lbl.Text为空字符串。因此,右侧评估为

"" + await wait_task

然后代码等待任务的结果,并返回4.因此表达式的结果是

"" + "4"

"4"。然后将其指定为this.async_lbl的文本。请注意,this.async_lbl.Text的起始值在发生await之前使用

另一方面,

string wait_value = await wait_task;
this.async_lbl.Text += wait_value;

扩展为

string wait_value = await wait_task;
this.async_lbl.Text = this.async_lbl.Text + wait_value;

这一次,代码等待wait_task,返回"4"。但与此同时,this.async_lbl.Text的值已更改为"3"。这一行

this.async_lbl.Text = this.async_lbl.Text + wait_value;

执行,右侧现在是

"3" + "4"

评估为"34“。