【问题标题】:How to break from List<T>.AsParallel().ForAll() using C#如何使用 C# 打破 List<T>.AsParallel().ForAll()
【发布时间】:2013-07-26 14:37:38
【问题描述】:

我正在使用 List.AsParallel().ForAll() PLINQ 实现。在循环内部,如果我发现一个条件成功,我希望循环立即跳出 ForAll() 循环。我怎样才能实现它?

这里是示例代码。

using System;
using System.Collections.Generic;
using System.Linq;

namespace Basics
{
class Program
{
    class Family
    {
        public int SNo { get; set; }
        public string Name { get; set; }
    }

    static List<Family> families = null;
    static Program()
    {
        families = new List<Family>()
        {
            new Family(){SNo = 10, Name="Richard"},
            new Family(){SNo = 33, Name="Xio Fung"},
            new Family(){SNo = 10, Name="Sean"},
            new Family(){SNo = 10, Name="Andrea"},
            new Family(){SNo = 20, Name="Bjorn"},
            new Family(){SNo = 20, Name="Isabella"},
            new Family(){SNo = 35, Name="Michael"},
            new Family(){SNo = 35, Name="Marie"}
        };
    }

    private static void Main()
    {
        Dictionary<int, List<Family>> theFamily = new Dictionary<int, List<Family>>();
        var groupedFamilies = families.GroupBy(family => family.SNo);

        groupedFamilies.AsParallel().ForAll(groupedFamily =>
        {
            int groupedFamilyCount = groupedFamily.Count();
            if (groupedFamilyCount == 1)
            {
                Console.WriteLine(groupedFamily.FirstOrDefault().Name);     
                // break; <-- I want to break if I find the count = 1
            }
        });                                 
        Console.ReadLine();
    }
}    

}

问候, 斯里拉姆

【问题讨论】:

  • 把那部分扔进它自己的方法和return ?
  • 我的意图是一旦条件满足就退出 ForAll()。我想知道在并行场景中打破循环。
  • 顺便说一下,您的示例中没有使用theFamily 字典。此外,您不应尝试在 FirstOrDefault 之后访问 Name 而不先检查 null。

标签: c#-4.0 plinq


【解决方案1】:

我相信Parallel.ForEach 会起作用:

Parallel.ForEach(groupedFamilies.AsParallel(), (groupedFamily, loopState) =>
            {
                int groupedFamilyCount = groupedFamily.Count();
                if (groupedFamilyCount == 1)
                {
                    Console.WriteLine(groupedFamily.FirstOrDefault().Name);
                    loopState.Stop(); // break if I find the count = 1

                }
            });

根据您的用例,您可能需要loopState.Break。使用 Stop() 进行 Any-like 操作,Break() 用于 First-like 操作。

在 Microsoft 的 articles on parallel programming with .NET 4 中有一篇关于该主题的好文章,名为“When To Use Parallel For Each Or PLINQ?”

【讨论】:

  • List.AsParallel().ForAll() 不可能吗?我确信 Parallel.ForEach() 会做。但我想知道前者是否可以实现同样的目标!
  • 不,我提到的文章解释了原因。基本上,您从 ForEach 的重载中获得的额外循环控制不能总是被 LINQ 翻译成其他语言。
  • 是的。我同意你的看法!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多