【问题标题】:.Continue starts before task is completed.Continue 在任务完成前开始
【发布时间】:2012-10-28 10:47:13
【问题描述】:

我在 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在任务完成后开始吗?

更新:

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

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

【问题讨论】:

  • 我认为你应该直接调用Task.Delay——而不是使用await关键字。
  • 你会注意到_实际上是一个Task<Task>,完全支持Justin所说的......
  • 其实使用Task.Delay(6)会产生预期的结果,但不会等待6秒。我认为删除整行几乎是一样的。

标签: c# .net wpf task-parallel-library async-await


【解决方案1】:

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

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

有关StartNewRun 的更多信息,请参阅Stephen Toub's post on the topic

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我认为你是对的 - await 将当前任务标记为已完成。虽然不是(至少从语义的角度来看不是)。由于 await 是当今所有软件的基本构建块,这意味着永远不要再依赖 ContinueWith。你不认为这是一个错误吗?
    【解决方案3】:

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

    【讨论】:

    • 他的代码有async 他的问题是他正在使用TaskFactory,它没有接受Func<Task>Func<Task<T>> 的重载,而Task.Run 确实有。
    猜你喜欢
    • 2012-01-17
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    相关资源
    最近更新 更多