私はTask
(それらの多く、約400)のセットを持っています:
IEnumerable<Task> tasks = ...
それらをすべて同時に実行してから、それぞれを待ちたいと思います。このコードを使用してタスクを実行します。
Task.Run(async () => { ... });
各タスクは非同期メソッド自体を実行するためasync
、ラムダにキーワードが必要です。これらのネストされたタスクの中にはHTTP
、送信されるリクエストとHTTP
受信されるレスポンスがあることで有名です。
すべてのタスクが完了するのを待つために、2 つの異なる方法を試しました。
await Task.WhenAll(tasks);
と
foreach (var task in tasks)
{
await task;
}
これは、先験的に、私にはまったく同じように見えます(しかし、もちろんそうではないようです。それ以外の場合は、そもそもここに投稿しません...)。
A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
最初の方法はタスクの実行を高速化しますが、出力ウィンドウにはこのようなものがたくさんあります。さらに、一部のタスクは、呼び出し後WaitingForActivation
の状態のままです。await Task.WhenAll()
2 番目の方法は遅く、タスクが同時に実行されていないように見えますHTTP
(タスクを待機する最初の方法では、ほぼ同時に応答が返されます)。また、ループfirst chance exception
を使用して各タスクを待機すると、出力ウィンドウに何も表示されず、ループ後の状態にあるforeach
タスクはありません。WaitingForActivation
一連のタスクを待機する「最良の」方法はWhenAll()
(少なくとも読みやすさのために) 使用することだと理解していますが、なぜこれら 2 つのメソッドの動作が異なるのでしょうか? どうすればこの問題を克服できますか? 理想的には、タスクを高速に実行し、すべてが終了したことを確認します (ラムダにサーバーエラーを処理するブロックがあり、誰かが尋ねる前にtry
catch
finally
を忘れていませんでした...)。if(httpClient != null) httpClient.Dispose()
finally
どんなヒントでも大歓迎です!
編集:
さて、私は別のことを試しました。追加した:
.ContinueWith(x => System.Diagnostics.Debug.WriteLine("#### ENDED = " + index)));
各タスクにindex
は、Task
. foreach
ループを使用すると、次のようになります。
#### ENDED = 0
#### ENDED = 1
#### ENDED = 2
#### ENDED = 3
#### ENDED = 4
...
を使用するWhenAll()
と、次のようになります。
#### ENDED = 1
#### ENDED = 3
#### ENDED = 0
#### ENDED = 4
#### ENDED = 8
...
したがって、ループを使用すると、すべてのタスクが同期的に実行されます...これは、システムがアルゴリズムによってまったくストレスを受けていないため、出力ウィンドウforeach
に何も表示されない理由を説明している可能性があります。First Chance Exception
EDIT2:
サンプルコード : http://pastebin.com/5bMWicD4
ここで利用可能な公共サービスを使用します: http://timezonedb.com/