c# - ParallelOptions.CancellationToken 似乎没用

标签 c# .net lambda task-parallel-library

ParallelOptions 的成员之一是 CancellationToken,其值旨在在 Parallel.ForEach 的 lambda 函数中访问。

使用它需要在调用 Parallel.ForEach 之前实例化 CacellationToken,那么为什么不能在 ForEach 的 Lambda 函数中直接访问该局部变量?

例如而不是:

var ct = new CancellationToken();
var options = new ParallelOptions { CancellationToken = ct }

Parallel.ForEach(source, options, (item) =>
{
     options.ct.ThrowIfCancellationRequested();
})

为什么我不能只使用:

var ct = new CancellationToken();

Parallel.ForEach(source, (item) =>
{
     ct.ThrowIfCancellationRequested();
})

它只是一个方便存放 token 的地方,还是有一些潜在的设计原因?

最佳答案

如果您将 CancellationToken 告诉 Parallel.ForEach,它可以在 token 被取消时停止处理。您可能不想从循环中抛出异常 - 您可能只想自己忽略取消标记,并且只希望处理您的项目的一个子集。

例如:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    static void Main()
    {
        var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
        var items = Enumerable.Range(0, 100).ToList();
        Parallel.ForEach(items, new ParallelOptions { CancellationToken = cts.Token },
            item =>
            {
                Console.WriteLine(item);
                Thread.Sleep(1000);
            });
    }
}

这将在三秒后以 OperationCanceledException 结束(而不是 AggregateException 如果一个/一些单独的任务失败,您会收到) - 但操作主体本身不需要知道取消 token 。当然,如果你有一个昂贵的操作,你不想为正在处理的最终项目不必要地完成你可以自己监控 token ,否则你可以让 Parallel.ForEach 注意并抛出异常本身。

关于c# - ParallelOptions.CancellationToken 似乎没用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39193219/

相关文章:

c# - ADAL - AcquireTokenSilentAsync 失败(Azure Active Directory 身份验证库)

c# - .NET 反射中的转换

c# - PropertyGrid,设计者与运行时的行为有何不同?

.net - sharepoint spweb 和 spsite 处置

python - string.format(...,**locals()) 的缩写形式

c# - JObject to dynamic 在 Newtonsoft.Json 9.0 中不起作用

c# - csla 验证错误 : Insert is an Invalid Operation

c# - 静态构造函数在同一个appdomain中被调用两次?

c# - 为什么包含异步 lambda 的方法本身不需要是异步的?

c# - 无法使用 Lambda 表达式检索值