Reputation: 12857
Bit of an interesting one here I think. I have a class thats in charge of "multiplexing" a number of processing operations onto a fixed number of threads. The typical case is a sort of producer/consumer problem, where each operation consists of a WaitHandle (in this case, the semaphore that tracks how many items are in the queue) and a delegate to invoke.
For example, If I have two producers (A and B), producing items into two seperate queues. Rather than create two consumer threads for each producer (A1,A2,B1,B2), I'm multiplexing the four consumers "threads" onto two threads. The code for this "multiplexer" runs something like this (simplified a bit):
WaitHandle[] waitHandles = new WaitHandle[2];
waitHandles[0] = NumberOfItemsFullInProducerAQueue;
waitHandles[1] = NumberOfItemsFullInProducerBQueue;
while(true)
{
int index = WaitHandle.WaitAny(waitHandles);
if(index == 0)
{
// handle the item from queue A
}
else
{
// handle the item from queue B
}
}
I'm trying to extend this concept onto a slightly more complicated example, where an action might need multiple wait handles to be satisfied before it is executed. I'm wondering if there is some sort of WaitHandle.Combine(waitHandle1, waitHandle2) call I can make to combine two wait handles together into a single wait handle. The end result would be something like:
A,B,C,D are waitHandles
E = Combine(A, B)
F = Combine(C, D)
waitHandles = { E, F }
while(true)
{
int index = WaitHandle.WaitAny(waitHandles);
if(index == 0)
{
}
else
{
}
}
Extra Points?
Although not a requirement, it might also be really nice if the combinations of wait handles could intersect. For example, something like this:
A,B,C are waitHandles
D = Combine(A, B)
E = Combine(A, C)
waitHandles = { D, E }
// same as above from here
Thanks for your help SO
Upvotes: 4
Views: 1233
Reputation: 27495
You might consider looking into the new Barrier class in the .NET 4 TPL (back-ported to 3.5 as part of Reactive Extensions. It's specifically designed for the scenarios you describe, where you need to block execution until multiple cooperating tasks have reached a checkpoint. You can also use the Task system to create sophisticated continuation paths, with one Task depending on two prior completing, dependent on a first Task completing and, if Exceptions occur at any point, having those Exceptions aggregated and reported in a central location.
Upvotes: 1