2009-05-22 11 views
10

Quiero llamar al WaitHandle.WaitOne(TimeSpan) en .NET, pero estoy en el hilo STA y bombea mensajes mientras espera. Por razones que están más allá del alcance de esta pregunta, necesito esperar sin bombeo. ¿Cómo puedo esperar a que se marque WaitHandle sin enviar mensajes?¿Cómo esperar en WaitHandle sin mensaje de bombeo?

En algunos casos, parece que WaitHandle.WaitOne no bombea mensajes. Pero a veces lo hace para algunos mensajes. Ver estos enlaces para obtener más información sobre lo siguiente:

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

Sé que el ya se ha respondido la pregunta, pero ¿puede dar una receta que demuestre que WaitHandle.WaitOne transfiere mensajes? Realmente no entiendo lo que está pasando aquí y tengo curiosidad. –

+0

wcoenen: He agregado enlaces en mi pregunta que indican que WaitOne a veces envía mensajes. –

Respuesta

8

WaitForSingleObject o WaitForMultipleObjects son esperas sin bombeo; usa p/invoke.

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

-Oisin

+0

Gracias. No sabía que podía pasar un SafeWaitHandle directamente en un método P/Invoke. Eso es genial. Gracias por el consejo. –

+0

Sí, el Marshaller .NET "sabe" acerca de los tipos que exponen un IntPtr (GetDangerousHandle en este caso, iirc), por lo que puede simplemente reemplazar ese parámetro en la firma y dejar que ocurra la magia ;-) – x0n

+0

Por alguna razón, el limitado El bombeo realizado por WaitOne() impide que se restauren los formularios minimizados al llamar a WaitOne() en Form.OnActivated. Me llevó 2 horas rastrear ese error hasta la llamada WaitOne(), pero gracias a tu respuesta aquí pude arreglarlo rápidamente :) ¡Gracias! – Daniel

3

Al parecer, este fue un change introduced in Microsoft Vista: CoWaitForMultipleHandles ahora despacha WM_PAINT mensajes.

Vista bug report.

Una solución consiste en utilizar el Kit de herramientas de compatibilidad de aplicaciones de Microsoft para establecer el indicador DisableNewWMPAINTDispatchInOLE para su aplicación.

1

Si estás en una aplicación WPF donde el despachador es el que ejecuta el mensaje bombas espera durante administrados, la forma más sencilla de desactivar la bomba mensaje durante su espera es a través de 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); 
} 
Cuestiones relacionadas