StephenCleary / AsyncEx

A helper library for async/await.
MIT License
3.49k stars 358 forks source link

AsyncProducerConsumerQueue.GetConsumingEnumerable() runs continuously #250

Closed anupshah2it closed 2 years ago

anupshah2it commented 2 years ago

I am using AsyncProducerConsumerQueue in place of ConcurrentQueue for my Pooling mechanism

Declaration, AsyncProducerConsumerQueue<PoolItem<T>> _workingQueue; //ConcurrentQueue<PoolItem<T>> _workingQueue List<PoolItem<T>> _items;

Before Implementation, This is a working code with ConcurrentQueue, and no issue with adding a range _items.AddRange(_workingQueue);

After Implementation, GetConsumingEnumerable returns IEnumerable but the code was lost in execution at this line, I tried to ToList() as well but no success. _items.AddRange(_workingQueue.GetConsumingEnumerable().ToList());

Any suggestion on this part? I tried with foreach to this GetConsumingEnumerable() to add it to _items list, but it returns the first item only and goes to the galaxy for the rest.

Please help, I don't want to revert my development, I hope there is a catch. Thank you!

StephenCleary commented 2 years ago

GetConsumingEnumerable will not complete until the underlying collection is marked as complete (CompleteAdding). Its API is similar to that of a BlockingCollection<T> wrapper around a ConcurrentQueue<T>. The producer/consumer queue API does not have a way to get all current items without completing the queue.

If you're updating code to be asynchronous, I recommend using System.Threading.Channels instead. The AsyncProducerConsumerQueue<T> type is kept in this library and still supported, but it is not recommended for new code.

anupshah2it commented 2 years ago

Thanks for the response. Will look forward to using System.Threading.Channels too In fact followed one of your articles on that front as well. Closing the ticket for now.