Task.WaitAll vs serialized task.results?

时间:2017-09-20 23:38:31

标签: c# task

忽略async / await解决方案这两组代码之间有什么区别吗?在这种情况下你真的需要Task.WaitAll吗?省略它会有任何负面后果吗?

public void ExampleA()
{
    Task<object> fooTask = _someFactory.StartFooTask();
    Task<object> barTask = _someFactory.StartBarTask();

    //misc code ...

    _fooResult = fooTask.Result;
    _barResult = barTask.Result;

    //more misc code ...
}

public void ExampleB()
{
    Task<object> fooTask = _someFactory.StartFooTask();
    Task<object> barTask = _someFactory.StartBarTask();

    //misc code ...

    Task.WaitAll(fooTask, barTask);

    _fooResult = fooTask.Result;
    _barResult = barTask.Result;

    //more misc code ...
}

exampleA对我来说更有意义,特别是在这种情况下,可能会发生一些更多的计算,因为一个任务结果可能比其他任务更快地需要?如果偶然需要的话,实际上会早点结束。

public void ExampleC()
{
    Task<object> fooTask = _someFactory.StartFooTask();
    Task<object> barTask = _someFactory.StartBarTask();

    //misc code ...

    _fooResult = fooTask.Result;

    // more misc code requiring _fooResult ...

    _barResult = barTask.Result;

    // more misc code requiring _barResult...
}

2 个答案:

答案 0 :(得分:1)

如果您想保证两个(所有)方法都已完成,您将使用WaitAll,否则第一个任务中的异常将阻止调用.Result或第二个任务,因此第二个方法可能没有按时间方法退出。

整体行为将非常接近

  • 抛出异常(.WhenAll与个人.Result)时存在细微差别,
  • 如果您没有.Result,那么您可以在WaitAll来电之间填写一些代码,
  • 这两个版本都会在ASP.Net/Winforms/WPF上下文中死锁。

答案 1 :(得分:0)

逻辑上,这两种方法都会阻止,直到fooTaskbarTask完成。

当然存在差异。您正在初始化和拆除不同的同步原语,但没有您会注意到的。

在第3个代码段中,您将描述您所描述的行为。但是,如果希望同时处理结果,则应使用continuation(Task.ContinueWith等)。

如果不传递经典建议,我无法解决此问题 - 如果可以避免,请不要致电Task.Wait或使用Task<T>.Result来阻止。你的同事会讨厌你。