Search code examples
c#multithreadingeventsblock

C# How to make a thread wait for either of two Manual Reset Events?


I have a thread that grabs messages from a concurrent queue and writes them to a network stream. The loop inside the thread looks like this:

while (!cancel.IsCancellationRequested)
{
    messageBus.outboundPending.WaitOne();
    var message = messageBus.GetFrom(Direction.Outbound);
    if (message == null) { continue; }

    MessageWriter.WriteMessage(networkStream, message, cancel, OnStreamClose).Wait(cancel);
}

The requirement is that the thread stops if the cancellation token is set. However, since it waits for pending messages in the queue, the thread will stay blocked. How could I "combine" both the cancellation token and the outbound event so that if either of them are set, the thread unblocks?

The only convoluted way that I can think of to make it work is to replace the outboundPending event with a new third event, and start two new threads: one that waits for the outbound event, and another that waits for the cancel event, and have both of them set the third event when they unblock. But that feels really bad.


Solution

  • Try WaitHandle.WaitAny and include the CancellationToken.WaitHandle.

    A discussion of a cancellable WaitAll can be found here