我有一组Task
(很多,大约 400 个):
IEnumerable<Task> tasks = ...
我想同时运行它们,然后等待它们中的每一个。我使用这段代码来运行任务:
Task.Run(async () => { ... });
每个任务都会自己运行异步方法,这就是为什么我需要async
lambda 中的关键字。在这些嵌套任务中,有众所周知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
一个一个地收到响应,而等待任务的第一种方式使它们几乎同时出现)。此外,当我使用循环等待每个任务并且没有任务具有循环后的状态时,first chance exception
我在输出窗口中根本看不到任何内容。foreach
WaitingForActivation
我理解等待一组任务的“最佳”方式是使用WhenAll()
(至少为了可读性),但为什么这两种方法的行为不同?我该如何克服这个问题?理想情况下,我希望任务能够快速运行并确保一切都结束(我try
catch
finally
在 lambda 中有一个块来处理服务器错误,而且我没有忘记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
,因为系统根本没有受到算法的压力。
编辑2:
示例代码: http: //pastebin.com/5bMWicD4
它使用此处提供的公共服务:http: //timezonedb.com/