views:

75

answers:

3

For some concurrent code, I want to connect a bunch of signals together like a circuit. In .NET we can do a WaitAll or WaitAny on a collection of signals. I want to do something like this:

WaitAny ( WaitAll (c1, c2), WaitAll (c3, c4) ) ;

Unfortunately, the library doesn't support composing these operations into more complex trees. My questions are (1) Is there a way to do this in .NET? (2) Is there a slick library for this in any language?

[edit: Cory asked for more details]

I want to build a message passing library. There could be 10K small concurrent queues, some with messages. I want to grab a message from a queue and execute a handler assigned to the queue. However, I can't grab the next message until the handler is done (single threaded per queue). So really I want to wait on both the queue (got a message?) and the code (finished with previous message?) before popping and executing the next item.

+3  A: 

I can't even believe I'm suggesting this but you could have other threads doing the WaitAll calls and triggering seperate signals (one unique per group of WaitAll) that you listen for in the WaitAny. Smells real bad and seems overly complex for something that should be simple. I'll probably regret clicking Post Your Answer ;-)

ManualResetEvent _Group1Event = new ManualReset(false);
ManualResetEvent _Group2Event = new ManualReset(false);

void SomeThread()
{
    ...
    WaitHandle.WaitAny(_Group1Event, _Group2Event);
    ...
}

void Group1WatcherThread()
{
    ...
    if (WaitHandle.WaitAll(c1, c2))
    {
       _Group1Event.Set();
    }
    ...
}

void Group2WatcherThread()
{
    ...
    if (WaitHandle.WaitAll(c3, c4))
    {
       _Group2Event.Set();
    }
    ...
}

Not sure on my WaitAll/WaitAny method calls but the example was just meant to demonstrate the idea not provide a complete solution.

Cory Charlton
I can't believe I'm upvoting this, either. :)
Tanzelax
Unfortunately, this would allocate a thread for every subtree in the circuit. I want nearly 10K of them, so this won't scale. The design of the API is difficult because, for example, how would the return value tell you which subtree is actually triggered in WaitAny? Think about really crazy deep trees of signals.
projectshave
@projectshave: Ya a thread per group wouldn't scale but you could create a single thread repsonsible for the `WaitAll` with low timeouts. Still not scalable. The WaitAny returns the index of the of the object in the array you passed in so you know which signal was fired. Maybe you could update your question with the base problem you are trying to solve and someone might have a better solution than the WaitAny(WaitAll(), WaitAll()) method you describe.
Cory Charlton
A: 

I don't believe there is support for this in .NET, nor in any language. I'll have to do it the hard way with low-level primitives.

projectshave
Yeah there is a way now, Rx Extensions.
Richard Hein
If you update your answer, I can undo the vote down. I didn't mean to vote down here.
Richard Hein
+1  A: 

I might be misunderstanding the problem. But would the reactive framework (Rx) be what you are looking for. It should allow composable events in the way that you are looking for.

http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx

Plural