C# 并行运行一个简单的 LINQ 查询

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13942998/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 10:10:28  来源:igfitidea点击:

Running a simple LINQ query in parallel

c#linqplinq

提问by user1002358

I'm still very new to LINQ and PLINQ. I generally just use loops and List.BinarySearchin a lot of cases, but I'm trying to get out of that mindset where I can.

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

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

Using "normal" LINQ - sorry, I'm unfamiliar with the terminology - I can do the following:

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

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

But I'd like to do this in parallel:

但我想并行执行此操作:

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

When I check the type of matchedStaff, it's a list of bools, which isn't what I want.

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

First of all, what am I doing wrong here, and secondly, how do I return a List<Staff>from this query?

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

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

returns IEnumerable<type>, not List<type>.

返回IEnumerable<type>,不是List<type>

采纳答案by darkey

For your first question, you should just replace Selectwith Where:

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

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

Selectis a projection operator, not a filtering one, that's why you are getting an IEnumerable<bool>corresponding to the projection of all your Staff objects from the input sequence to bools returned by your Matchesmethod call.

Select是投影运算符,而不是过滤运算符,这就是为什么您要获得IEnumerable<bool>对应于所有 Staff 对象从输入序列到Matches方法调用返回的 bool 的投影的原因。

I understand it can be counter intuitive for you not to use selectat all as it seems you are more familiar with the "query syntax" where select keyword is mandatory which is not the case using the "lambda syntax" (or "fluent syntax" ... whatever the naming), but that's how it is ;)

我知道完全不使用可能会违反直觉,因为您select似乎更熟悉“查询语法”,其中 select 关键字是强制性的,而使用“lambda 语法”(或“流畅语法”)则不然。 ..无论命名如何),但这就是它的方式;)

Projections operators, such a Select, are taking as input an element from the sequence and transform/projects this element somehow to another type of element (here projecting to booltype). Whereas filtering operators, such as Where, are taking as input an element from the sequence and either output the element as such in the output sequence or are not outputing the element at all, based on a predicate.

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

As for your second question, AsEnumerablereturns an IEnumerableas it's name indicates ;) If you want to get a List<Staff>you should rather call ToList()(as it's name indicates ;)) :

至于你的第二个问题,正如它的名字所表明AsEnumerableIEnumerable那样返回一个;) 如果你想得到一个List<Staff>你应该打电话ToList()(正如它的名字所表明的那样;)):

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

Hope this helps.

希望这可以帮助。

回答by binki

There is no need to abandon normal LINQ syntax to achieve parallelism. You can rewrite your original query:

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

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

The parallel LINQ (“PLINQ”) version would be:

并行 LINQ(“PLINQ”)版本将是:

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

To understand where the bools are coming from, when you write the following:

要了解bools 的来源,请编写以下内容:

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

That is equivalent to the following query syntax:

这等效于以下查询语法:

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

As stated by darkey, if you want to use the C# syntax instead of the query syntax, you should use Where():

正如darkey 所说,如果你想使用C# 语法而不是查询语法,你应该使用Where()

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