C# 何时对异步委托使用OrderByCompletion(Jon Skeet)与Parallel.ForEach
最近,伦敦国家数据中心的Jon Skeet谈到了C#5异步/等待,并提出了“按完成排序”的想法,即异步任务列表。链接 我有点困惑,或者说我不确定什么时候这种技术更适合使用 我无法理解此示例与下面示例之间的区别C# 何时对异步委托使用OrderByCompletion(Jon Skeet)与Parallel.ForEach,c#,async-await,c#-5.0,C#,Async Await,C# 5.0,最近,伦敦国家数据中心的Jon Skeet谈到了C#5异步/等待,并提出了“按完成排序”的想法,即异步任务列表。链接 我有点困惑,或者说我不确定什么时候这种技术更适合使用 我无法理解此示例与下面示例之间的区别 var bag = new ConcurrentBag<object>(); Parallel.ForEach(myCollection, async item => { // some pre stuff var response = await GetData
var bag = new ConcurrentBag<object>();
Parallel.ForEach(myCollection, async item =>
{
// some pre stuff
var response = await GetData(item);
bag.Add(response);
// some post stuff
}
var-bag=新的ConcurrentBag();
Parallel.ForEach(myCollection,异步项=>
{
//一些预先准备的东西
var响应=等待获取数据(项目);
添加(响应);
//一些邮件
}
或者像Stephen Toub解释的那样
编辑:找到了一篇来自Stephen Toub的文章,解释了“按完成排序”“完成任务时处理任务”。值得一读。读了这篇文章后,我可以清楚地理解其工作原理以及何时使用此技巧
- 不要使用
执行Parallel.ForEach
代码。async
不理解Parallel.ForEach
,因此您的lambda将变为async
,无法正常工作(async void
将在所有工作完成之前返回;异常将无法正确处理;可能还有其他问题)Parallel.ForEach
- 使用类似于
的方法,当您有一组对象(而不是ForEachAsync()
s)时,您希望为每个对象执行一些Task
操作,这些操作应该并行执行async
- 使用
当您有一组OrderByCompletion()
时,您希望对每个任务
的结果执行一些操作(异步或非异步),这些操作不应并行执行,您希望根据任务
完成的顺序执行操作任务
Action
,因此匿名方法是一个异步void
方法。这意味着它将被启动,除了检查它的任何副作用之外,您无法检查它的状态。特别是,如果出现任何问题,您将无法捕获并处理它e例外
不过,假设没有任何问题,结果将在完成时添加到包中。在任何操作完成之前,包将为空
相反,OrderByCompletion
返回一个立即包含所有未完成任务的IEnumerable
。您可以等待第五个元素,并在任何五个任务完成后继续。例如,当您想运行大量任务并定期将表单更新为sh时,这可能很有用进展如何
您提供的第三个选项,ForEachAsync
,其行为类似于ForEach
,只是它可以正确执行,不会出现上述问题。Parallel.ForEach
已经用于多线程。如果您查看ForEachAsync()的版本
在本文后面,他们不会等到每个任务完成后才开始下一个任务。@svick啊,它有多个不同的ForEachAsync
定义,不仅在实现细节上有所不同,而且在用户可见的行为上也有所不同。谢谢,我没有注意到。该方法在Stephen Toub的博客上有文档记录。@DanEsparza是的,我没有再链接到它,因为它已经链接到了问题中。
Parallel.ForEach(myCollection, async item =>