Parallel.Foreach/For 如何调用 BlockingCollection.Take?有或没有取消令牌
本文关键字:BlockingCollection Take 令牌 取消 调用 For Foreach 何调用 Parallel | 更新日期: 2023-09-27 18:33:19
try
{
ParallelOptions Options = new ParallelOptions();
Options.CancellationToken = base.DownloadCancellation.Token;
Parallel.ForEach(base.BlockingCollection1, Options, ActiveSeeder =>
{
//...
});
}
catch
{
if (base.DownloadCancellation.IsCancellationRequested)
return false;
}
Parallel.Foreach/For 调用 BlockingCollection1.Take 函数是否带有或不带有我放入 ParallelOptions 的 CancelToken?
有机会知道吗?
Parallel.ForEach()
根本不调用Take()
,因此您的问题无效。
相反,它会像对待任何其他IEnumerable<T>
一样对待集合,这意味着它将调用其GetEnumerator()
,然后处理结果。记录了GetEnumerator()
为BlockingCollection
做什么:
与
GetConsumingEnumerable
不同,BlockingCollection<T>.IEnumerable<T>.GetEnumerator
返回一个不修改基础集合的标准枚举器。如果其他线程在调用GetEnumerator
时同时添加或删除元素,则枚举器返回的元素可能不表示集合的当前状态。
如果要在迭代时从集合中删除项,可以使用 GetConsumingEnumerable()
,它确实具有需要 CancellationToken
的重载。但这实际上不会很好地工作,所以最好使用来自 ParallelExtensionsExtras(GitHub 上的代码)的GetConsumingPartitioner()
。