PLINQ延迟执行

时间:2010-03-08 18:49:55

标签: c# multithreading yield plinq delayed-execution

考虑到执行延迟,我试图理解并行性如何使用PLINQ。这是一个简单的例子。

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

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

如果我们并行执行此操作,可能会在“收据”结果返回之前开始评估“救济”。但是一旦查询知道“收据”会导致真实结果,其他线程会立即产生吗?

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

1 个答案:

答案 0 :(得分:4)

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

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

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

旁注:

与LINQ to Objects不同,PLINQ并不真正使用延迟执行。当您在AsParallel()上致电IEnumerable<T>时,生成的ParallelQuery<T>实际上会开始并行处理您的例程。延迟执行会大大降低PLINQ的有效性,因为如果不事先创建工作分区和调度,就不可能并行安排。


编辑:

考虑到这一点 - 如果你的lambda非常昂贵,你可能想考虑使用CancellationToken。我在博客中详细介绍了how cancellation in PLINQ works。通常情况下,您只需使用令牌并调用ThrowIfCancellationRequested() - 但是,您也可以使用CancellationToken并检查IsCancellationRequested,这样可以让您的lambda“提前退出”,为您提供一种方法马上停止后台处理...