PLINQ 延迟执行

问题描述 投票:0回答:1

我试图了解在延迟执行的情况下并行性如何使用 PLINQ 工作。这是一个简单的例子。

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

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

如果我们并行执行此操作,则“relief”的评估可能在“receipt”结果返回之前就开始了。但是一旦查询知道“receipt”会产生真实的结果,其他线程会立即屈服吗?

就我而言,这很重要,因为“任何”测试可能非常昂贵,并且我希望释放处理器来执行其他任务。

c# multithreading yield plinq delayed-execution
1个回答
5
投票

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

一旦

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

但是,当前在您的 Any() 方法中执行 lambda 表达式的任何线程仍将执行,因为它们无法知道另一个线程已成功。它将阻止新线程调用

Any()
,但不会取消“非常昂贵”委托中的所有线程。
附注:

PLINQ 与 LINQ to Objects 不同,它并不真正使用延迟执行。当您在

AsParallel()

上调用

IEnumerable<T>
时,生成的
ParallelQuery<T>
实际上将开始并行处理您的例程。延迟执行会极大地降低 PLINQ 的有效性,因为如果不提前创建工作分区和调度,就不可能并行调度。

编辑:

考虑到这一点后 - 如果您的 lambda 非常昂贵,您可能需要考虑使用

CancellationToken

。我在博客中详细介绍了PLINQ 中的取消如何工作。通常,您只需使用令牌并调用 ThrowIfCancellationRequested() - 但是,您也可以使用 CancellationToken 并检查 IsCancellationRequested,这将使您的 lambda“提前退出”,为您提供一种停止后台处理更快...

© www.soinside.com 2019 - 2024. All rights reserved.