9

我在 C#、VS2012、WPF 4.5 中有以下代码。我的期望是,.ContinueWith将在任务完全完成后执行(这是延续的全部目的,不是吗?)。

这应该导致 2 in 的值finalResult

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一个任务完全完成后我不能依靠启动吗?

更新:

贾斯汀的回答只是启发我检查以下内容:

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。有没有办法可靠地等待包含awaits 的任务完成?

4

3 回答 3

10

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

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

有关StartNewvs的更多信息Run,请参阅Stephen Toub 关于该主题的帖子

于 2012-11-08T15:28:43.887 回答
4

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

于 2012-11-08T09:04:54.977 回答
-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() ”!!!

于 2015-10-30T16:11:14.330 回答