Question

         try
         {
             ParallelOptions Options = new ParallelOptions();
             Options.CancellationToken = base.DownloadCancellation.Token;
             Parallel.ForEach(base.BlockingCollection1, Options, ActiveSeeder =>
                 {
                     //...
                 });
         }
         catch
         {
             if (base.DownloadCancellation.IsCancellationRequested)
                 return false;
         }

Does the Parallel.Foreach/For call the BlockingCollection1.Take function With or with out the CancellationToken I put into the ParallelOptions?

Is there any chance to find out?

Was it helpful?

Solution

Parallel.ForEach() does not call Take() at all, so your question is invalid.

Instead, it will treat the collection like any other IEnumerable<T>, which means it will call its GetEnumerator() and then work with the result. What GetEnumerator() does for BlockingCollection is documented:

Unlike GetConsumingEnumerable, BlockingCollection<T>.IEnumerable<T>.GetEnumerator returns a standard enumerator that does not modify the underlying collection. If other threads are adding or removing elements concurrently when GetEnumerator is called, then the elements returned by the enumerator might not represent the current state of the collection.

If you want to remove items from the collection as you iterate, you could use GetConsumingEnumerable(), which does have an overload that takes CancellationToken. But this won't actually work very well, so it's better to use GetConsumingPartitioner() from ParallelExtensionsExtras (code on GitHub).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top