并行运行简单的LINQ查询

use*_*358 19 c# linq plinq

我对LINQ和PLINQ仍然很陌生.我通常只是List.BinarySearch在很多情况下使用循环,但我正试图摆脱那种心态.

public class Staff
{
  // ...
  public bool Matches(string searchString)
  {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

使用"普通"LINQ - 对不起,我不熟悉术语 - 我可以做到以下几点:

var matchedStaff = from s
                     in allStaff
                  where s.Matches(searchString)
                 select s;
Run Code Online (Sandbox Code Playgroud)

但我想并行执行此操作:

var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));
Run Code Online (Sandbox Code Playgroud)

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

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

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

回报IEnumerable<type>,而不是List<type>.

dar*_*key 32

对于您的第一个问题,您应该替换SelectWhere:

var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));
Run Code Online (Sandbox Code Playgroud)

Select这是一个投影操作符,而不是过滤操作符,这就是为什么你得到一个IEnumerable<bool>对应于从输入序列到Matches方法调用返回的bool的所有Staff对象的投影.

我理解你可以反直觉,因为你select似乎更熟悉"查询语法",其中select关键字是强制性的,而不是使用"lambda语法"(或"流利语法")的情况. ..无论命名如何),但它就是这样;)

投影操作符,例如Select,将序列中的元素作为输入,并将此元素以某种方式转换/投影到另一种类型的元素(此处投影到bool类型).而过滤运算符(例如)Where将来自序列的元素作为输入,并且基于谓词在输出序列中输出元素,或者根本不输出元素.

至于你的第二个问题,如它的名字所示AsEnumerable返回一个IEnumerable;)如果你想获得一个,List<Staff>你应该调用ToList()(因为它的名字表示;)):

return allStaff.AsParallel().Select(/* something */).ToList();
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.


bin*_*nki 8

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

var matchedStaff = from s in allStaff
    where s.Matches(searchString)
    select s;
Run Code Online (Sandbox Code Playgroud)

并行LINQ("PLINQ")版本将是:

var matchedStaff = from s in allStaff.AsParallel()
    where s.Matches(searchString)
    select s;
Run Code Online (Sandbox Code Playgroud)

要了解bools的来源,请在撰写以下内容时:

var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));
Run Code Online (Sandbox Code Playgroud)

这相当于以下查询语法:

var matchedStaff = from s in allStaff.AsParallel() select s.Matches(searchString);
Run Code Online (Sandbox Code Playgroud)

如darkey所述,如果您想使用C#语法而不是查询语法,则应使用Where():

var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));
Run Code Online (Sandbox Code Playgroud)