A Non-blocking Wait for Event or Timeout in C#
We often want to wait for an Event in a thread while letting other stuff proceed. Or … delay a method in the UI thread while letting stuff update.
I recently created a Worker thread to display a webcam image. The image is received asynchronously and the COM webcam object lives in the thread so you’d think it’s easy to do this. Unfortunately, controlling the webcam features (brightness, contrast, …) has to happen within this thread. What I wanted was a way to Wait for the image ready Event while still letting stuff communicate with the thread objects.
Unfortunately all of the Wait methods for an Event block the thread. As of .NET 4.5 it turns out there’s a very simple and clear way to wait for an event to trigger while still allowing other things to proceed. Code below:
This is short but relatively opaque. A DispatcherFrame is a way to manually push messages through the Windows message loop.
First, create a DispatcherFrame.
Then, start a worker thread that asynchronously waits for the event/timeout.
Blocking call frame.PushFrame - which pushes Windows messages until frame.Continue becomes false. So this code is paused but the thread continues to process messages.
When the event WaitOne triggers in the worker thread, frame.Continue is set to false. PushFrame ends in the primary thread and we return the result.
By the way, if you’re in the UI thread (for example) and you just want to delay for some amount of time you can replace the event.WaitOne with a Thread.Sleep. This will delay for a fixed time but still allow messages to go through.