是否建议prevTask.Wait()与ContinueWith一起使用(来自Tasks库)? [英] Is prevTask.Wait() recommended to be used with ContinueWith (from the Tasks library)?

查看:96
本文介绍了是否建议prevTask.Wait()与ContinueWith一起使用(来自Tasks库)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以最近我被告知,我如何将.ContinueWith用于任务不是正确的使用方式。我还没有在互联网上找到证据,所以我会问大家,看看答案是什么。这是我如何使用.ContinueWith的示例:

So I was told recently that how I was using my .ContinueWith for Tasks was not the proper way to use them. I have yet to find evidence of this on the internet so I will ask you guys and see what the answer is. Here is an example of how I use .ContinueWith:

public Task DoSomething()
{
    return Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Step 1");
    })
    .ContinueWith((prevTask) =>
    {
        Console.WriteLine("Step 2");
    })
    .ContinueWith((prevTask) =>
    {
        Console.WriteLine("Step 3");
    });
}

现在我知道这是一个简单的示例,它将很快运行,但是只是假设每个任务都需要更长的时间。因此,我被告知的是,在.ContinueWith中,您需要说prevTask.Wait();。否则,您可以在上一个任务完成之前进行工作。那有可能吗?我以为我的第二个第三个任务只有在他们之前的任务完成后才能运行。

Now I know this is a simple example and it will run very fast, but just assume each task does some longer operation. So, what I was told is that in the .ContinueWith, you need to say prevTask.Wait(); otherwise you could do work before the previous task finishes. Is that even possible? I assumed my second & third task would only run once their previous task finishes.

有人告诉我如何编写代码:

What I was told how to write the code:

public Task DoSomething()
{
    return Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Step 1");
    })
    .ContinueWith((prevTask) =>
    {
        prevTask.Wait();
        Console.WriteLine("Step 2");
    })
    .ContinueWith((prevTask) =>
    {
        prevTask.Wait();
        Console.WriteLine("Step 3");
    });
}


推荐答案

恩……认为当前的某些答案缺少某些东西:异常会发生什么?

Ehhh.... I think some of the current answers are missing something: what happens with exceptions?

您会打电话给 Wait 的唯一原因在延续过程中,将观察到延续过程本身的前身存在潜在的例外。如果在 Task< T> 的情况下访问 Result ,并且手动访问,也会发生相同的观察结果。 Exception 属性。
坦白说,我不会打电话给等待或访问 Result ,因为如果有异常,您会支付重新筹集的费用,这是不必要的开销。取而代之的是,您只需要检查 IsFaulted 属性,就可以关闭之前的 Task 属性。或者,您可以通过链接多个兄弟姐妹连续项来创建分支工作流,这些连续性仅基于成功或失败而使用 TaskContinuationOptions.OnlyOnRanToCompletion TaskContinuationOptions.OnlyOnFaulted

The only reason you would call Wait in a continuation would be to observe a potential exception from the antecedent in the continuation itself. The same observation would happen if you accessed Result in the case of a Task<T> and also if you manually accessed the Exception property. Frankly, I wouldn't call Wait or access Result because if there is an exception you'll pay the price of re-raising it which is unnecessary overhead. Instead you can just check the IsFaulted property off the antecedent Task. Alternatively you can create forked workflows by chaining on multiple sibling continuations that only fire based on either success or failure with TaskContinuationOptions.OnlyOnRanToCompletion and TaskContinuationOptions.OnlyOnFaulted.

现在,没有必要在延续中观察到前例的例外情况,但是如果您说,例如,您可能不希望工作流程向前发展,步骤1失败。在那种情况下:在您的 ContinueWith 调用中指定 TaskContinuationOptions.NotOnFaulted 将会阻止继续逻辑甚至触发。

Now, it's not necessary to observe the exception of the antecedent in the continuation, but you may not want your workflow to move forward if, say, "Step 1" failed. In that case: specifying TaskContinuationOptions.NotOnFaulted to your ContinueWith calls would prevent the continuation logic from ever even firing.

请记住,如果您自己的延续未观察到异常,那么正在等待总体工作流程完成的人将是一个要观察的人。它。他们要么正在等待上游的任务 等待,要么是自己继续进行以了解何时完成。如果是后者,则它们的延续将需要使用上述观察逻辑。

Keep in mind that, if your own continuations don't observe the exception, the person who is waiting on this overall workflow to complete is going to be the one to observe it. Either they're Waiting on the Task upstream or have tacked on their own continuation to know when it is complete. If it is the latter, their continuation would need to use the aforementioned observation logic.

这篇关于是否建议prevTask.Wait()与ContinueWith一起使用(来自Tasks库)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆