这是一个简单的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的输出不同?
谢谢!
以下是反映的代码:
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;
}
答案 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
“。