-->

并行运行一个简单的LINQ查询(Running a simple LINQ query in par

2019-08-04 07:04发布

我仍然很新的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 s,这不是我想要的。

首先,我究竟做错了什么,其次,我怎么返回一个List<Staff>此查询?

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

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

Answer 1:

关于第一个问题 ,你应该只替换SelectWhere

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

Select是投影算 ,而不是一个过滤一个,这就是为什么你得到一个IEnumerable<bool>对应于从输入序列中的所有您的员工对象的投影由您返回的bool Matches方法调用。

我的理解可能是直觉你不使用select ,因为它似乎你更熟悉的“查询语法”里选择关键字是强制性这是不使用“lambda语法”(或“一口流利的语法”在所有的情况...无论命名),但是这是怎么回事;)

突起运营商,这样的Select ,从所述序列作为输入的元件和变换/项目此元件以某种方式到另一种类型的元素(此处突出到bool型)。 而过滤运营商,如Where ,在元件作为输入的元件从该序列,要么输出作为这样在输出序列或不outputing的元件在所有的,基于谓词。

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

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

希望这可以帮助。



Answer 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;

为了理解其中的bool s是,当你写下面的未来:

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));


文章来源: Running a simple LINQ query in parallel
标签: c# linq plinq