2012-12-31 3 views
1

내가하려는 것은 내 프로세스 내에서 창 (0123)에 붙잡고 기다리는 것입니다. (아무 것도 제어 할 수는 없지만).NativeWindow에서 메시지 대기

메시지를 기다리려면 AutoResetEvent을 사용하려고합니다.

WaitForMaterialUpdate 메서드는 NativeWindow을 창에 연결하고 메시지를받을 때까지 차단합니다.

내가 사용하고있는 코드입니다 :

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); 
    } 
} 

나는 매우 디버깅 환경에서 아니지만, 나는 창은 대기 기간 동안 WM_TIMER 메시지를받는 사실에 있음을 MessageBox, 아직 WaitOne 사용 확인했다 항상 반환하기 전에 전체 5000ms 제한 시간을 기다립니다.

어디서 잘못 생각하나요?

+0

UI 스레드에서 실행 중입니까? – SLaks

+0

@SLaks 예. 다른 스레드에서'WaitOne'을 호출해야합니까? 그렇다면, 왜 아직도이 상태에서도'MessageBox' 팝업이 나옵니까? – Rotem

+0

'MessageBox'는 UI 메시지를 출력합니다. – SLaks

답변

1

WaitOne()은 차단 호출입니다.
WaitOne()이 반환 될 때까지 UI 스레드는 메시지를받지 않습니다. UI 스레드가 메시지를받을 때 대기 핸들을 설정 했으므로 교착 상태가 발생합니다.

백그라운드 스레드에서이 작업을 수행하거나 메시지를받을 때 콜백을 호출하면됩니다.

+0

나는 본다. 감사. 환경의 특성 때문에 동 기적으로이 작업을 수행해야하므로'while (! msgReceived) Application.DoEvents()'를 사용하여 'AutoResetEvent'대신 직접 메시지를 보내야합니다. – Rotem

+0

이것은 정확하지 않습니다. UI 스레드에서 WaitOne()이 호출되면 CLR에서 메시지 루프가 발생합니다. http://stackoverflow.com/questions/4540244/how-is-this-possible-onpaint-processed-while-in-waitone을 참조하십시오. –