2009-05-22 9 views
10

Voglio chiamare WaitHandle.WaitOne(TimeSpan) in .NET, ma sono nel thread STA e pompa i messaggi in attesa. Per motivi che vanno oltre lo scopo di questa domanda, devo aspettare senza il pompaggio. Come posso aspettare che un WaitHandle venga segnalato senza inviare messaggi?Come attendere WaitHandle senza pompare messaggi?

In alcuni scenari, sembra che WaitHandle.WaitOne non invii messaggi. Ma a volte lo fa per alcuni messaggi. Vedere questi link per ulteriori informazioni su questo:

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

So che la la domanda è già stata risolta, ma puoi dare una ricetta che dimostri che WaitHandle.WaitOne pompa messaggi? Non capisco davvero cosa sta succedendo qui e sono curioso. –

+0

wcoenen: Ho aggiunto dei link nella mia domanda che indicano che WaitOne a volte pompa messaggi. –

risposta

8

WaitForSingleObject o WaitForMultipleObjects sono attese non pompaggio; usa p/invoke.

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

-Oisin

+0

Grazie. Non sapevo che potresti passare SafeWaitHandle direttamente in un metodo P/Invoke. Questo è figo. Grazie per il consiglio. –

+0

Sì, il marshaller .NET "conosce" i tipi che espongono un IntPtr (GetDangerousHandle in questo caso, iirc), quindi puoi semplicemente sostituire quel parametro nella firma e lasciare che la magia accada ;-) – x0n

+0

Per qualche motivo, la limitazione il pumping fatto da WaitOne() impedisce il ripristino dei moduli minimizzati quando si chiama WaitOne() in Form.OnActivated. Mi ci sono voluti 2 ore per rintracciare quel bug alla chiamata di WaitOne(), ma grazie alla tua risposta qui ho potuto sistemarlo rapidamente :) Grazie! – Daniel

3

A quanto pare questo è stato un change introduced in Microsoft Vista: CoWaitForMultipleHandles ora invia WM_PAINT messaggi.

Vista bug report.

Una soluzione alternativa consiste nell'utilizzare Application Compatibility Toolkit di Microsoft per impostare il flag DisableNewWMPAINTDispatchInOLE per l'applicazione.

1

Se siete in un'applicazione WPF dove il Dispatcher è colui che esegue il messaggio di pompe attese durante gestiti, il modo più semplice per disattivare la pompa di messaggio durante la vostra attesa è via 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); 
} 
Problemi correlati