I'm making use of the (frankly great) BlockingCollection<T>
type for a heavily multithreaded, high-performance app.
There's a lot of throughput through the collection and on the micro-level it's highly performant. However, for each 'batch' it will always be ended by flagging the cancellation token. This results in an exception being thrown on any waiting Take
call. That's fine, but I would have settled for a return value or output parameter to signal it, because a) exceptions have an obvious overhead and b) when debugging, I don't want to manually turn off break-on-exception for that specific exception.
The implementation seems intense, and in theory I suppose I could disassemble and recreate my own version that didn't use exceptions, but perhaps there's a less complex way?
I could add a null
(or if not, a placeholder) object to the collection to signify the process should end, however there also needs to be a means to abort nicely, i.e. wake up waiting threads and tell them somehow that something's gone on.
So - alternative collection types? Recreate my own? Some way to abuse this one?
(Some context: I went with BlockingCollection<T>
because it has an advantage over manual locking around a Queue
. As best I can tell the use of threading primitives is superb and in my case, a few milliseconds here-and-there and optimal core is use crucial.)
Edit: I've just opened a bounty for this one. I don't believe Anastasiosyal's answer covers the query I raise in my comment of it. I know this is a tough problem. Is anyone able to assist?
Take
and I need to be able to signal an abort from somewhere other than the producer. I may be missing a trick though.. – BeltaneGetConsumingEnumerable
is.. maybeMoveNext
blocks by default, and returns false if it's all cancelled! Anyone know about that..? – Beltaneyield
y) which still seems to throw an exception, at least internally, possibly further – BeltaneAdd
, the otherTake
, and potentially any thread is flagging theCancellationToken
. @Representational - check the source, it's usingyield
and using methods which use the same underlying methods, i.e. exceptions are used – BeltaneAdd
then there's no way to cancel by attempting to add another item. – BeltaneCancellationToken.ThrowIfCancellationRequested
internally on methods that use it. I'm just asking if there's an alternative implementation or way of achieving the same thing without doing that. RewritingCancellationToken
,BlockingCollection<>
andSemaphoreSlim
is the only thing I've come up with so far.. – Beltane