tbi*_*hel 5 c# multithreading yield delayed-execution plinq
鉴于延迟执行,我试图了解并行性如何使用 PLINQ 工作。这是一个简单的例子。
string[] words = { "believe", "receipt", "relief", "field" };
bool result = words.AsParallel().Any(w => w.Contains("ei"));
Run Code Online (Sandbox Code Playgroud)
使用 LINQ,我希望执行达到“收据”值并返回 true,而不执行其余值的查询。
如果我们并行执行此操作,则“relief”的评估可能在“receipt”的结果返回之前就已开始。但是一旦查询知道“receipt”会导致一个真实的结果,其他线程是否会立即yield?
就我而言,这很重要,因为“任何”测试可能非常昂贵,而且我希望释放处理器以执行其他任务。
不幸的是,其他线程不会立即“屈服”。
一旦Any()找到有效元素,PLINQ 调度程序将停止调度新线程以检查新元素。任何现有的分区程序也将收到取消请求,这将阻止这些分区调用Any()另一个项目。
但是,当前在您的Any()方法中执行 lambda 表达式的任何线程仍将执行,因为它们无法知道另一个线程已成功。它将阻止新线程调用到Any(),但不会取消“非常昂贵”委托中的所有线程。
旁注:
与 LINQ to Objects 不同,PLINQ 并没有真正使用延迟执行。当您调用AsParallel()an 时IEnumerable<T>,ParallelQuery<T>生成的 将实际开始并行处理您的例程。延迟执行会显着降低 PLINQ 的有效性,因为如果不提前创建工作分区器和调度,就不可能并行调度。
编辑:
考虑到这一点后 - 如果您的 lambda 非常昂贵,您可能需要考虑使用CancellationToken。我在博客中详细介绍了 PLINQ 中的取消是如何工作的。通常,您只需使用令牌并调用ThrowIfCancellationRequested() - 但是,您也可以使用 CancellationToken 并检查IsCancellationRequested,这将使您的 lambda“提前退出”,为您提供一种更快停止后台处理的方法。 ..
| 归档时间: |
|
| 查看次数: |
357 次 |
| 最近记录: |