PLINQ延迟执行

PLINQ延迟执行

问题描述:

我想了解如何使用PLINQ并行性,如果延迟执行。这是一个简单的例子。PLINQ延迟执行

string[] words = { "believe", "receipt", "relief", "field" }; 
bool result = words.AsParallel().Any(w => w.Contains("ei")); 

使用LINQ,我希望执行以达到“回执”值并返回true,而不执行查询的值的其余部分。

如果我们同时这样做,“救济”的评估可能在“回执”结果返回之前就开始了。但是一旦查询知道“收据”会产生真实结果,其他线程是否会立即产生?

在我的情况下,这很重要,因为“any”测试可能非常昂贵,我想释放处理器以执行其他任务。

不幸的是,其他线程不会立即“屈服”。

只要Any()找到有效元素,PLINQ调度程序就会停止调度新线程以检查新元素。任何现有的分区程序也将收到取消请求,这将阻止这些分区在另一个项目上调用Any()

然而,当前正在执行的内您Any()方法lambda表达式任何线程仍然会执行,因为没有办法让他们知道,另一个线程成功。它将阻止新线程调用Any(),但不会取消“非常昂贵”代表中的所有线程。

在一个侧面说明:

PLINQ,不像LINQ到对象,并没有真正使用延迟执行。在IEnumerable<T>上拨打AsParallel()时,生成的ParallelQuery<T>实际上将开始并行处理您的例程。延迟执行会大大降低PLINQ的有效性,因为如果不提前创建工作分区和时间安排,就不可能同时进行安排。


编辑:

思考之后 - 如果你的拉姆达是非常昂贵的,你可能要考虑使用CancellationToken。我详细地写了一篇关于how cancellation in PLINQ works的博客。通常情况下,您只需使用令牌并致电ThrowIfCancellationRequested() - 但是,您也可以使用CancellationToken并检查IsCancellationRequested,它可以让您将lambda“提前退出”,从而为您提供一种更快地停止后台处理的方法...

+0

http://msdn.microsoft.com/en-us/library/dd997425(VS.100).aspx表示延迟执行原则仍在PLINQ中发挥作用......你能澄清一下你在你的意思方面呢? – tbischel 2010-03-08 19:17:51

+0

@tbischel:他们这样做,他们不......这个评论有点误导。不同之处在于,在LINQ中,每个元素只按请求执行(延迟)。在PLINQ中,只要您发出第一个请求,就会设置一个'Partitioner ',它开始将您的工作安排到多个线程。最终的累计结果直到请求才会被推回,但处理发生在请求元素之前。 (如果您请求结果的元素1,元素1,2,3和4可能全部被调度,并立即开始“工作”......) – 2010-03-08 19:33:10