我有一组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