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/