我对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
对于您的第一个问题,您应该替换Select为Where:
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)
希望这可以帮助.
没有必要放弃正常的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)