并行运行简单的LINQ查询
我仍然是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
的类型时,它是bool
的列表,这不是我想要的。
首先,我在这里做错了什么,其次,如何从这个查询中返回List
?
public List Search(string searchString) { return allStaff.AsParallel().Select(/* something */).AsEnumerable(); }
返回IEnumerable
,而不是List
。
对于您的第一个问题 ,您应该将Select
替换为Where
:
var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));
Select
是一个投影操作符 ,而不是过滤操作符 ,这就是为什么你得到一个IEnumerable
对应于你输入序列中所有Staff对象的投影到你的Matches
方法调用返回的IEnumerable
。
据我所知,你可以反对使用select
,因为你似乎更熟悉“查询语法”,其中select关键字是强制性的,而不是使用“lambda语法”(或“流利语法”)的情况……无论命名如何,但它就是这样;)
投影运算符(例如Select
将序列中的元素作为输入,并将此元素以某种方式转换/投影到另一种类型的元素(此处投影到bool
类型)。 过滤运算符(例如Where
将序列中的元素作为输入,并在输出序列中输出元素,或者根本不基于谓词输出元素。
至于你的第二个问题 , AsEnumerable
返回一个IEnumerable
因为它的名字表示;)如果你想得到一个List
你应该调用ToList()
(因为它的名字表示;)):
return allStaff.AsParallel().Select(/* something */).ToList();
希望这可以帮助。
没有必要放弃正常的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;
要了解bool
的来源,请在撰写以下内容时:
var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));
这相当于以下查询语法:
var matchedStaff = from s in allStaff.AsParallel() select s.Matches(searchString);
如darkey所述 ,如果要使用C#语法而不是查询语法,则应使用Where()
:
var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));