。继续在任务完成之前开始
我在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() ”!!!