【问题标题】:Running a simple LINQ query in parallel并行运行一个简单的 LINQ 查询
【发布时间】:2012-12-06 06:01:38
【问题描述】:

我对 LINQ 和 PLINQ 还是很陌生。在很多情况下,我通常只使用循环和List.BinarySearch,但我会尽量摆脱这种心态。

public class Staff
{
  // ...
  public bool Matches(string searchString)
  {
    // ...
  }
}

使用“普通”LINQ - 抱歉,我不熟悉术语 - 我可以执行以下操作:

var matchedStaff = from s
                     in allStaff
                  where s.Matches(searchString)
                 select s;

但我想并行执行:

var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));

当我检查matchedStaff 的类型时,它是bools 的列表,这不是我想要的。

首先,我在这里做错了什么,其次,我如何从这个查询中返回List<Staff>

public List<Staff> Search(string searchString)
{
  return allStaff.AsParallel().Select(/* something */).AsEnumerable();
}

返回IEnumerable&lt;type&gt;,而不是List&lt;type&gt;

【问题讨论】:

  • 您仍然可以在 PLINQ 中使用查询语法(这就是它的名称):from s in allStaff.AsParallel() where s.Matches(searchString) select s

标签: c# linq plinq


【解决方案1】:

对于您的第一个问题,您只需将Select 替换为Where

var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));

Select 是投影运算符,而不是过滤运算符,这就是为什么您会得到一个 IEnumerable&lt;bool&gt; 对应于从输入序列到您返回的布尔值的所有 Staff 对象的投影Matches方法调用。

我知道你完全不使用select 可能是反直觉的,因为你似乎更熟悉“查询语法”,其中选择关键字是强制性的,而使用“lambda 语法”的情况并非如此(或“流利的语法”......无论命名如何),但就是这样;)

投影运算符,例如Select,将序列中的一个元素作为输入,并以某种方式将此元素转换/投影到另一种类型的元素(这里投影到bool 类型)。而过滤运算符,例如Where,将序列中的一个元素作为输入,并根据谓词在输出序列中输出该元素或根本不输出该元素.

至于您的第二个问题AsEnumerable 会返回 IEnumerable,正如其名称所示;) 如果你想得到一个List&lt;Staff&gt;,你应该打电话给ToList()(因为它的名字表明;)):

return allStaff.AsParallel().Select(/* something */).ToList();

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    没有必要放弃正常的 LINQ 语法来实现并行性。您可以重写原始查询:

    var matchedStaff = from s in allStaff
        where s.Matches(searchString)
        select s;
    

    并行 LINQ (“PLINQ”) 版本为:

    var matchedStaff = from s in allStaff.AsParallel()
        where s.Matches(searchString)
        select s;
    

    要了解bools 的来源,请编写以下代码:

    var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));
    

    相当于下面的查询语法:

    var matchedStaff = from s in allStaff.AsParallel() select s.Matches(searchString);
    

    As stated by darkey,如果你想使用C#语法而不是查询语法,你应该使用Where()

    var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));
    

    【讨论】:

      猜你喜欢
      • 2018-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多