。继续在任务完成之前开始

我在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语句上启动了continuation。

这是预期的行为吗? 我在这里错过了什么吗? 任务完成后我不能依赖ContinueWith启动吗?

更新:

贾斯汀的回答激发了我检查以下内容:

 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 s的任务完成?

当您将async委托传递给Task.Factory.StartNew ,返回的Task仅代表该委托的第一部分(直到它await尚未完成的某个部分为止)。

但是,如果将async委托传递给新的Task.Run方法(由于此原因而包含该方法),则返回的Task表示整个委托。 因此,您可以按预期使用ContinueWith 。 (虽然await通常是比ContinueWith更好的选择)。

有关StartNew vs Run更多信息,请参阅Stephen Toub关于该主题的post 。

await将立即将控制权返回给调用函数,在这种情况下,调用函数是您的任务的StartNew。 这意味着任务将完成并执行ContinueWith。 如果您真的希望在ContinueWith之前完成任务,那么请不要等待Task.Delay。

我在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() ”!!!