I've come across a problem that I can readily define but for the life of me can't seem to digest the MSDN for the best possible solution. It's been a while since I had to actually think about parallel processing outside of UI responsiveness.
So say, I have a Concurrent collection of Tasks that need to be processed. For example maybe it is loading data to various consumers by type (Consumer1, Consumer2, Consumer3...Consumer[N]) the underlying Task of sending the data is the same for each task but each consumer can only accept one source at a time
Basically, I want to process as much in parallel as possible with the caveat that I can only send 1 task to each consumer at a time. So if a current Job for a Consumer is already in progress then I should move to the next item in the collection and leave it for when the Job in progress for that consumer has completed. The Concurrent collection could also be added to at any time externally and if we had new types we'd need additional threads.
I guess what my question boils down to is how do I customize the "Take" from the collection so that I only grab the next Task with a property that designates it has a Consumer that doesn't already have a Job in progress.
Any ideas on what I'm missing here or if I'm even on the right path?
Example we have a Mediator Queue with Tasks associated with Banking transactions.
So we might add to our mediator queue (Let's say send SummaryData and Send TransactionData are using the same interface contract to send data)
- SendTransactionData -> Bank1
- SendTransactionData -> Bank2
- SendSummaryData -> Arbiter
- SendTransactionData -> Bank1
- SendTransactionData -> Bank3
- SendTransactionData -> Bank1
- SendTransactionData -> Bank2
1,2,3,5 can be processed in parallel but due to their own system(s) each consumer can only accept one input at a time transaction 4 must wait for transaction 1 to be completed and Transaction 6 must wait for transaction 4 to process. Similarly Transaction 7 must wait for transaction 2.
Before any of the initial processes have completed someone may add another grouping.
SendSummaryData -> Arbiter
SendTransactionData -> Bank1
SendTransactionData -> Bank4
10 can be picked up immediately if a thread is available, but 8 and 9 must be queued behind their other related tasks.
Obviously there would be better ways to design a system to accomplish this but these are essentially the specs I'm looking to satisfy.