I already have multiple async actors polling remote servers for data, and need this data persisted to a database.
It seems like a classic consumer-producer pattern, with multiple Poller
producers and a single Persister
consumer. IProducerConsumerCollection<T>
seems a great option here, and it seems to suit my purposes better that T
is a simple chunk of data DataUnit
, not a unit of work - I want the consumer to decide what work is done on the data, not the producer. i.e. I am favoring a data-queue not a task-queue.
So, using BlockingCollection<DataUnit>
would give a trivial implementation along the lines of while(...){ DoStuff(blockingCollection.Take(); }
(checks omitted for simplicity) but BlockingCollection.Take()
obviously commits a thread which blocks idly waiting for data, which though not a huge problem would be nice to avoid.
My first question is simply: why is there no TakeAsync
method? Does the fact it's not there imply I've misunderstood the designed use?
Another option could be to use ConcurrentQueue<DataUnit>
directly:
while(...)//checks and stuff
{
DataItem item;
if(concurrentQueue.TryTake(out item);
DoStuff(item);
else
await Task.Delay(50);
}
I dislike hard-coding a delay of 50ms but is this a reasonable approach? If not, is there an obvious alternative?