c# - PLINQ延迟执行

标签 c# multithreading yield plinq delayed-execution

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

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

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

如果我们并行执行此操作,则“relief”的评估可能在“receipt”的结果返回之前就已开始。但是一旦查询知道“receipt”会导致一个 true 的结果,其他线程会立即 yield 吗?

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

最佳答案

不幸的是,其他线程不会立即“让步”。

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

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

旁注:

PLINQ 与 LINQ to Objects 不同,它并不真正使用延迟执行。当您调用 AsParallel()IEnumerable<T> 上, ParallelQuery<T>生成的实际上将开始并行处理您的例程。延迟执行会显着降低 PLINQ 的效率,因为如果不提前创建工作分区器和调度,就不可能进行并行调度。


编辑:

考虑之后 - 如果您的 lambda 非常昂贵,您可能需要考虑使用 CancellationToken .我在博客上详细介绍了 how cancellation in PLINQ works .通常,您只需使用 token 并调用 ThrowIfCancellationRequested() - 但是,您也可以使用 CancellationToken 并检查 IsCancellationRequested ,这将使您的 lambda“提前退出”,为您提供一种更快停止后台处理的方法......

关于c# - PLINQ延迟执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2403826/

相关文章:

c# - 从属性网格重置属性

ruby - rspec yield block ,但调用原始

python - 有没有办法添加/修改使用yield创建的生成器的属性?

Ruby:不允许在 'yield' 之后放置空格

c# - Azure,工作连接字符串,但表示尚未初始化

c# - 尝试异步方法失败

c# - 使用 MVVM 的 WPF 脚手架?

python - 使用 python 线程锁和循环导入时的意外行为

multithreading - 2.7转换后Mapreduce不再起作用

python - 重新排列数组的多线程方法?