Rei*_*ica 1 .net c# 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();
})
Run Code Online (Sandbox Code Playgroud)
为什么我不能只使用:
var ct = new CancellationToken();
Parallel.ForEach(source, (item) =>
{
ct.ThrowIfCancellationRequested();
})
Run Code Online (Sandbox Code Playgroud)
它只是存放令牌的方便地方,还是这种设计有一些潜在的原因?
如果你告诉Parallel.ForEach有关CancellationToken,当令牌被取消了,它将停止处理。您可能不想从循环中引发异常-您可能只想自己忽略取消令牌,而只是希望将处理您的项的子集。
例如:
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);
});
}
}
Run Code Online (Sandbox Code Playgroud)
该操作将在三秒钟后完成OperationCanceledException(而不是AggregateException如果一个或某些单个任务失败,您将收到)-但动作主体本身不需要知道取消标记。当然,如果您有昂贵的操作,不想对正在处理的最终项目不必要地完成操作,则可以自己监视令牌,否则,您可以仅Parallel.ForEach通知并引发异常本身。