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函数使用或不使用了CancelOt,我将其放入ParallelOptions?
有没有机会找到答案?
答案 0 :(得分:4)
Parallel.ForEach()
根本没有 致电Take()
,因此您的问题无效。
相反,它会像其他任何IEnumerable<T>
一样处理集合,这意味着它将调用其GetEnumerator()
,然后使用结果。 What GetEnumerator()
does for BlockingCollection
is documented:
与
GetConsumingEnumerable
不同,BlockingCollection<T>.IEnumerable<T>.GetEnumerator
返回不修改基础集合的标准枚举器。如果在调用GetEnumerator
时其他线程同时添加或删除元素,则枚举器返回的元素可能不代表集合的当前状态。
如果您想在迭代时从集合中删除项目,可以使用GetConsumingEnumerable()
,它有an overload that takes CancellationToken
。但实际上这不会很好,所以最好使用GetConsumingPartitioner()
from ParallelExtensionsExtras。