Last active
July 2, 2018 07:56
-
-
Save ReubenBond/98de2cede0d57a989ededa8e113b0f39 to your computer and use it in GitHub Desktop.
Demonstrates an InvalidOperationException when using BlockingCollection with ConcurrentBag as the underlying collection and calling TryTakeFromAny
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
using System.Threading; | |
namespace BlockingCollectionConcurrentBagException | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// We only hold a reference to the outer BlockingCollection, not the inner ConcurrentBag | |
var blockingCollection = new BlockingCollection<int>(new ConcurrentBag<int>()); | |
// Produce elements into the collection. | |
var i = 0; | |
var producerFunc = new WaitCallback[1]; | |
producerFunc[0] = | |
state => | |
{ | |
if (blockingCollection.Count == 0) blockingCollection.Add(i++); | |
else Thread.Yield(); | |
ThreadPool.QueueUserWorkItem(producerFunc[0]); | |
}; | |
ThreadPool.QueueUserWorkItem(producerFunc[0]); | |
// Concurrently pull elements off the collection. | |
var consumerFunc = new WaitCallback[1]; | |
consumerFunc[0] = | |
ignored => | |
{ | |
var success = false; | |
do | |
{ | |
try | |
{ | |
// THIS IS WHERE THE EXCEPTION OCCURS | |
success = blockingCollection.TryTake(out _); | |
} | |
catch (Exception exception) | |
{ | |
Console.WriteLine(exception); | |
} | |
} while (success); | |
ThreadPool.QueueUserWorkItem(consumerFunc[0]); | |
}; | |
// Start two competing consumers. | |
ThreadPool.QueueUserWorkItem(consumerFunc[0]); | |
ThreadPool.QueueUserWorkItem(consumerFunc[0]); | |
Thread.Sleep(-1); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment