I have a BlockingCollection. Producer tasks add items to it, and consumer tasks remove items.
Now I want to limit the number of items in the collection, automatically discarding old data if more items are added. The collection should never contain more than the N
most recently added items at the same time.
So, if the producers add new items faster than the consumers remove them, I want the consumers to process only the newest items.
I can limit the size of a BlockingCollection
in its constructor, but of course that just means it blocks when adding more items, not that it removes old items.
(I do not want blocking on the producer side, only the consumer side should block when retrieving items from an empty collection.)
My current solution is a hack, and only works for a size limit of 1:
(And I am not quite sure it works reliable at all.)
// My consumer task:
foreach (var item in blockingCollection.GetConsumingEnumerable())
{
var lastItem = item;
var lastItemTmp = item;
while (blockingCollection.TryTake(out lastItemTmp))
lastItem = lastItemTmp;
// Now lastItem contains the most recent item in the collection,
// and older items have been discarded.
// Proceed consuming lastItem ...
}
Is there a cleaner solution?