Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 何时对异步委托使用OrderByCompletion(Jon Skeet)与Parallel.ForEach_C#_Async Await_C# 5.0 - Fatal编程技术网

C# 何时对异步委托使用OrderByCompletion(Jon Skeet)与Parallel.ForEach

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

最近,伦敦国家数据中心的Jon Skeet谈到了C#5异步/等待,并提出了“按完成排序”的想法,即异步任务列表。链接

我有点困惑,或者说我不确定什么时候这种技术更适合使用

我无法理解此示例与下面示例之间的区别

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
    不理解
    async
    ,因此您的lambda将变为
    async void
    ,无法正常工作(
    Parallel.ForEach
    将在所有工作完成之前返回;异常将无法正确处理;可能还有其他问题)

  • 使用类似于
    ForEachAsync()
    的方法,当您有一组对象(而不是
    Task
    s)时,您希望为每个对象执行一些
    async
    操作,这些操作应该并行执行

  • 使用
    OrderByCompletion()
    当您有一组
    任务
    时,您希望对每个
    任务
    的结果执行一些操作(异步或非异步),这些操作不应并行执行,您希望根据
    任务
    完成的顺序执行操作

这几乎肯定不是您想要的。委托的类型为
Action
,因此匿名方法是一个
异步void
方法。这意味着它将被启动,除了检查它的任何副作用之外,您无法检查它的状态。特别是,如果出现任何问题,您将无法捕获并处理它e例外

不过,假设没有任何问题,结果将在完成时添加到
包中。在任何操作完成之前,
包将为空

相反,
OrderByCompletion
返回一个立即包含所有未完成任务的
IEnumerable
。您可以
等待第五个元素,并在任何五个任务完成后继续。例如,当您想运行大量任务并定期将表单更新为sh时,这可能很有用进展如何


您提供的第三个选项,
ForEachAsync
,其行为类似于
ForEach
,只是它可以正确执行,不会出现上述问题。

Parallel.ForEach
已经用于多线程。如果您查看
ForEachAsync()的版本
在本文后面,他们不会等到每个任务完成后才开始下一个任务。@svick啊,它有多个不同的
ForEachAsync
定义,不仅在实现细节上有所不同,而且在用户可见的行为上也有所不同。谢谢,我没有注意到。该方法在Stephen Toub的博客上有文档记录。@DanEsparza是的,我没有再链接到它,因为它已经链接到了问题中。
Parallel.ForEach(myCollection, async item =>