I'm exposing an IProducerConsumerCollection(T)
from an interface that will periodically add items for another thread to consume.
public interface IProducer<T>
{
IProducerConsumerCollection<T> ProducerCollection { get; }
}
I was trying to use a BlockingCollection(T)
with the existing collection, but it appears that adding to the IProducerConsumerCollection(T)
directly is not supported:
var queue = new ConcurrentQueue<string>();
var blockingCollection = new BlockingCollection<string>(queue);
var task1 = Task.Run(() => {
Console.WriteLine("Dequeued " + blockingCollection.Take());
Console.WriteLine("Dequeued " + blockingCollection.Take());
});
var task2 = Task.Run(() => {
Console.WriteLine("Enqueueing Hello");
queue.Enqueue("Hello");
Console.WriteLine("Enqueueing World");
queue.Enqueue("World");
});
Task.WaitAll(task1, task2);
This will hang indefinitely as the BlockingCollection(T)
will not notice the new items.
Is there similar functionality to the BlockingCollection(T).Take
method or is there anything simpler than:
static async Task<T> TakeAsync<T>(
IProducerConsumerCollection<T> collection,
CancellationToken token
)
{
T result;
while(!collection.TryTake(out result))
{
await Task.Yield();
token.ThrowIfCancellationRequested();
}
return result;
}
This will hang indefinitely as the BlockingCollection(T) will not notice the new items.
Indeed - because you're adding directly to queue
. From the documentation:
Do not modify the underlying collection directly. Use the
BlockingCollection<T>
methods to add or remove elements. TheBlockingCollection<T>
object can become corrupted if you change the underlying collection directly.
So your calls to queue.Enqueue
should use blockingCollection
instead.
In terms of your TaskAsync
- you can use TryTake
with a timeout of Infinite
(-1) instead... but you might want to read Stephen Cleary's blog post on a similar topic , too...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.