我有一組Task
(很多很多,大約400個):等待大量的任務
IEnumerable<Task> tasks = ...
我想在同一時間運行它們,然後等待他們中的每一個。我使用這段代碼運行的任務:
Task.Run(async() => { ... });
每個任務的運行異步方法本身,這就是爲什麼我需要在拉姆達的async
關鍵字。在這些嵌套的任務中,出現了衆所周知的HTTP
請求和接收到的HTTP
響應。
我嘗試了兩種不同的方式來等待所有的任務來完成:
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()
。
第二種方法是慢,它看起來像的任務不同時運行(我收到由一個HTTP
響應中的一個,而等待任務的第一種方式讓他們來幾乎都在同一時間)。另外,當我使用foreach
循環等待每個任務並且在循環後沒有任何任務具有WaitingForActivation
狀態時,我在輸出窗口中完全看不到first chance exception
。
我知道等待一組任務的「最佳」方式是使用WhenAll()
(至少爲了便於閱讀),但爲什麼這兩個方法的行爲不同?我怎樣才能克服這個問題?理想情況下,我希望任務能夠快速運行,並確保一切都結束(我有一個try
catch
finally
塊在lambda中處理服務器錯誤,我沒有忘記finally
中的if(httpClient != null) httpClient.Dispose()
,然後任何人都會問......)。
歡迎任何提示!
編輯:
好吧,我試過另外一件事。我說:
.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/
這並沒有使他們同步運行(他們已經運行),但你得到的結果,同時,並在訂貨您創建它們 –
在你'await'一個'Task'應該不會影響如何是的方式該任務已執行。這真的是你的代碼,而不是像'foreach(var job in jobs){等待Task.Run(...); ''?你可以發佈一個簡短但完整的示例代碼來證明這一點嗎? – svick
@svick我在我的文章中添加了一個示例代碼:-) – Max