views:

57

answers:

1

I am using TPL support to implement a multithreading producer-consumer pattern in C#. With the handy BlockingCollection and Task classes, the job is easy, until I need to handle exceptions.

As we all know, the consumer Tasks objects will be blocked when there is no item in BlockingCollection for consumption and to prevent those Tasks from waiting infinitely, it is vital to call BlockingCollection.CompleteAdding() to explicitly tell everyone that there is no more item adding to the BlockingCollection and to wake up any waiting Tasks.

In my case, it is possible that between the launch of multiple consumers and the call of BlockingCollection.CompleteAdding(), there is an exception thrown out. When the exception is thrown, the execution stops, which means the BlockingCollection.CompleteAdding() will never be called and the Tasks will wait forever.

And in my case, I have a big cake and the producer-consumer is just one piece of it while the exception can be thrown from other pieces of the cake, which means that there is no easy way for the producer-consumer's piece of cake to detect the exception and to handle the cleanup.

Is there any useful pattern to encounter such a situation?

+1  A: 

I would suggest you use a finally block which calls CompleteAdding() to ensure that the queue is always closed, even if an exception is thrown.

Anthony Williams