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?