2009-05-22 1 views
10

Ich möchte WaitHandle.WaitOne(TimeSpan) in .NET anrufen, aber ich bin auf dem STA-Thread und es pumpt Nachrichten während des Wartens. Aus Gründen, die über den Rahmen dieser Frage hinausgehen, muss ich warten ohne Pumpen. Wie kann ich darauf warten, dass ein WaitHandle signalisiert wird, ohne Nachrichten zu pumpen?Warten auf WaitHandle, ohne dass die Nachricht gepumpt wird?

Es scheint in einigen Szenarien, dass WaitHandle.WaitOne keine Nachrichten pumpt. Aber es tut manchmal für einige Nachrichten. Sehen Sie diese Links für weitere Informationen dazu:

  1. Managed and Unmanaged Threading in Microsoft Windows
  2. Managed blocking
+0

ich das wissen Frage wurde bereits beantwortet, aber können Sie ein Rezept geben, das zeigt, dass WaitHandle.WaitOne Nachrichten pumpt? Ich verstehe nicht wirklich, was hier vor sich geht, und ich bin neugierig. –

+0

wcoenen: Ich habe in meiner Frage Links hinzugefügt, die darauf hinweisen, dass WaitOne manchmal Nachrichten pumpt. –

Antwort

8

WaitForSingleObject oder WaitForMultipleObjects sind nicht-Pumpen wartet; Verwenden Sie p/invoke.

[DllImport("kernel32", SetLastError=true, ExactSpelling=true)] 
public static extern Int32 WaitForSingleObject(SafeWaitHandle handle, Int32 milliseconds); 

-Oisin

+0

Danke. Ich wusste nicht, dass Sie ein SafeWaitHandle direkt in eine P/Invoke-Methode übergeben können. Das ist cool. Danke für den Tipp. –

+0

Yeah, der .NET Marshaller "weiß" über Typen, die ein IntPtr (GetDangerousHandle in diesem Fall, Iirc) offenbaren, so dass Sie einfach diesen Parameter in der Signatur ersetzen können und die Magie passieren lassen ;-) – x0n

+0

Aus irgendeinem Grund ist das begrenzt Durch das Ausführen von WaitOne() wird verhindert, dass minimierte Formulare beim Aufruf von WaitOne() in Form.OnActivated wiederhergestellt werden. Nahm mich 2 Stunden, um diesen Fehler bis zum WaitOne() Anruf zu verfolgen, aber dank Ihrer Antwort hier konnte ich es schnell beheben :) Danke! – Daniel

3

Anscheinend war dies ein change introduced in Microsoft Vista: CoWaitForMultipleHandles entsendet nun WM_PAINT Nachrichten.

Vista bug report.

Eine Problemumgehung besteht darin, das Application Compatibility Toolkit von Microsoft zum Festlegen des DisableNewWMPAINTDispatchInOLE-Flags für Ihre Anwendung zu verwenden.

1

Wenn Sie in einer WPF-Anwendung sind, wo der Dispatcher ist derjenige, der die Nachricht läuft Pumpen während verwalteten wartet, der einfachste Weg, um die Nachricht Pumpe während Ihrer Wartezeit zu deaktivieren ist über Dispatcher.DisableProcessing:

// The Dispose() method is called at the end of the using statement. 
// Calling Dispose on the DispatcherProcessingDisabled structure, 
// which is returned from the call to DisableProcessing, will 
// re-enable Dispatcher processing. 
using (Dispatcher.CurrentDispatcher.DisableProcessing()) 
{ 
    // Do work while the dispatcher processing is disabled. 
    Thread.Sleep(2000); 
}