1

What I am trying to do is catch and wait for a WM_TIMER message on a window within my process (though one which I have no control of).

I am trying to use an AutoResetEvent in order to wait for the message.

The WaitForMaterialUpdate method connects the NativeWindow to the window, and blocks until it receives a message.

This is the code I am using:

public class MaterialEditorWindow : NativeWindow
{
    private const int WM_TIMER = 0x0113;

    private AutoResetEvent waiter;

    public void WaitForMaterialUpdate(IntPtr handle)
    {
        waiter = new AutoResetEvent(false);
        AssignHandle(handle);
        waiter.WaitOne(5000);
        ReleaseHandle();
    }

    protected override void WndProc(ref Message m)
    {
         if (m.Msg == WM_TIMER) waiter.Set();
         base.WndProc(ref m);
    }
}

I am not in a very debuggable environment, but I have confirmed using MessageBox that the window is in fact receiving WM_TIMER messages during the wait period, yet WaitOne always waits the full 5000 ms timeout period before returning.

Any idea where I'm going wrong?

Rotem
  • 21,452
  • 6
  • 62
  • 109

1 Answers1

1

WaitOne() is a blocking call.
The UI thread will not receive any messages until WaitOne() returns. Since you set the wait handle when the UI thread receives a message, you have a deadlock.

You need to do this on a background thread, or simply call a callback when you receive the message.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • I see. Thanks. As I need this done synchronously due the specifics of the environment, I will probably go with `while (!msgReceived) Application.DoEvents()` to pump the messages myself instead of the `AutoResetEvent`. – Rotem Dec 31 '12 at 17:00
  • This is not accurate, the CLR pumps a message loop when WaitOne() is called on an UI thread. See http://stackoverflow.com/questions/4540244/how-is-this-possible-onpaint-processed-while-in-waitone – Hans Passant Dec 31 '12 at 17:37