2017-09-20 7 views
-1

async/awaitソリューションを無視すると、これらの2つのコードセットに違いはありますか?この場合、Task.WaitAllが本当に必要でしょうか?それを省略することに否定的な結果があるだろうか?Task.WaitAllとシリアル化されたtask.results?

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は、特に場合は、私にはさらに多くの理にかなって、1タスクの結果として起こる可能性があり、いくつかのより多くを計算後、すぐに他の人を必要とするかもしれないがあるかもしれませんどこ?偶然に必要なものがあれば、実際には早く終了する。論理的に

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... 
} 
+1

私が「WaitAll」で見る1つの問題は、いずれかのタスクに例外がある場合は、AggregateExceptionをスローします。 'ExampleA'では、例外を投げたタスクが分かっていて、それらを別々に処理する仕組みを持つことができます。 –

答えて

1

WaitAllを使用すると、最初のタスクの例外は.Resultまたは2番目のタスクの呼び出しを妨げ、メソッドが終了するまでに2番目のメソッドが完了しないことがあります。

全体的に動作が非常に近くなります

  • 例外がスローされる小さな違いがあります(.WhenAll対個別.Result)、
  • あなたが出てpoinedてきたように、あなたは.Result呼び出した場合との間にいくつかのコードを収めることができWaitAll
  • 両方のバージョンがASP.Net/Winforms/WPFコンテキストでデッドロックします。
+0

私はコンソールアプリケーションで作業しています。デッドロックが心配されていないので、上記のコンテキストが発生しました。 – WillFM

0

fooTaskbarTaskが完了するまで、両方の方法をブロックします。

もちろん、相違があります。同期プリミティブを初期化して破棄していますが、気づくことはありません。

3番目のスニペットでは、記述した動作が発生します。ただし、結果を同時に処理する場合は、続行(Task.ContinueWithなど)を使用する必要があります。

古典的なアドバイスを受けずにこのコードに対処することはできません。回避することができれば、Task.Waitに電話をかけたり、Task<T>.Resultを使用してブロックしたりしないでください。あなたの同僚はあなたを憎むでしょう。

関連する問題