using System; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; namespace JD.Threading { public static class Win32MessageLoop { #region Methods public static void WaitAndPump(WaitHandle waitHandle) { var safeHandle = waitHandle.SafeWaitHandle; IntPtr[] handles = new IntPtr[1]; const int QS_ALLINPUT = 0x04FF; const int MWMO_INPUTAVAILABLE = 0x0004; const int WAIT_OBJECT_0 = 0; const int WAIT_FAILED = -1; const int WAIT_MESSAGE = WAIT_OBJECT_0 + 1; // + handles.Length while (true) { Application.DoEvents(); bool mustRelease = false; safeHandle.DangerousAddRef(ref mustRelease); handles[0] = safeHandle.DangerousGetHandle(); int result = MsgWaitForMultipleObjectsEx(1, handles, Timeout.Infinite, QS_ALLINPUT, MWMO_INPUTAVAILABLE); if (mustRelease) { safeHandle.DangerousRelease(); } switch (result) { case WAIT_FAILED: Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error()); break; case WAIT_OBJECT_0: return; case WAIT_MESSAGE: break; default: throw new NotImplementedException(); } } } #endregion #region Dll Interop [DllImport("User32.dll", SetLastError = true)] private static extern int MsgWaitForMultipleObjectsEx(int nCount, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] IntPtr[] pHandles, int dwMilliseconds, int dwWakeMask, int dwFlags); #endregion } }