Friday, 5 October 2012

Boolean logic and WaitHandles

I had a fun five minutes today trying to express a wait on three WaitHandles X, Y and Z in which I want both of X and Y to be signalled, but have Z as an early escape. It’s soon clear that you can’t express:

(X && Y) || Z

With WaitAll and WaitOne, e.g. as

WaitHandle.WaitAll{ X, Y } || Z.WaitOne

because WaitAll blocks.

Thanks to the fact that boolean operations are distributive I can recompose (X && Y) || Z as

(X || Z) && (Y || Z)

and apply that structure in this case as

WaitHandle.WaitAny{ X, Z } && WaitHandle.WaitAny{ Y, Z }

with the proviso that the state of Z is unchanged by the Wait – for example, as long as Z does not autoreset.

My particular example was in managing a task workflow – the kind of thing that’s (almost certainly) made redundant by the TPL in .NET 4+. In my case, X and Y are a throttle on in-flight tasks, and a turnstile that admits workers when tasks are newly runnable. Z is an early escape in case of shutdown or exception.

I’m hoping that some clever bod will spot this and point out there’s a perfectly natural and convenient way of expressing this more simply.

No comments: