我在C#,VS2012,WPF 4.5中有以下代码。
我的期望是,.ContinueWith
将在任务完成后执行(这是一个延续的完整目的,不是吗?)。
这应该导致finalResult
中的值为2。
int myTestInt = 0;
Task task = Task.Factory.StartNew(async () =>
{
myTestInt = 1;
await Task.Delay(TimeSpan.FromSeconds(6));
myTestInt = 2;
}).ContinueWith(_ =>
{
int finalResult = myTestInt;
});
实际上,finalResult
的值分配为1。所以似乎已经在await
语句上开始了延续。
这是预期的行为吗?我在这里错过了什么吗?在任务完成后我不能依赖ContinueWith
来启动吗?
更新
Justin的回答激发了我检查以下内容:
int myTestInt = 0;
Task task=Task.Factory.StartNew(async () =>
{
myTestInt = 1;
await Task.Delay(TimeSpan.FromSeconds(6));
myTestInt = 2;
});
task.Wait();
int result2 = myTestInt;
finalResult仍设置为1.是否无法可靠地等待包含await
的任务完成?
答案 0 :(得分:10)
当您将async
委托传递给Task.Factory.StartNew
时,返回的Task
仅代表该委托的第一部分(直到它await
的某个部分为止尚未完成)。
但是,如果您将async
委托传递给新的Task.Run
方法(由于此原因而包含该方法),则返回的Task
代表整个委托。因此,您可以按预期使用ContinueWith
。 (虽然await
通常比ContinueWith
更好。
有关StartNew
vs Run
的详情,请参阅Stephen Toub's post on the topic。
答案 1 :(得分:4)
await将立即将控制权返回给调用函数,在这种情况下,调用函数是您的任务的StartNew。这意味着任务将完成并执行ContinueWith。 如果你真的希望在ContinueWith之前完成任务,那么就不要等待Task.Delay。
答案 2 :(得分:-1)
我在MSDN中看到了这个: - )
public async void button1_Click(object sender, EventArgs e)
{
pictureBox1.Image = await Task.Run(async() =>
{
using(Bitmap bmp1 = await DownloadFirstImageAsync())
using(Bitmap bmp2 = await DownloadSecondImageAsync())
return Mashup(bmp1, bmp2);
});
}
所以不要忘记“async()”!!!