Parallel.Foreach / For如何调用BlockingCollection.Take?有或没有CancellationToken

时间:2013-09-28 15:39:17

标签: c# multithreading parallel.foreach blockingcollection cancellationtokensource

         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?

有没有机会找到答案?

1 个答案:

答案 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