Example #1
0
        // ------------------------------------------------------
        //
        // Private Methods
        //
        // ------------------------------------------------------

        #region Private Methods

        // Infinite loop. Wait for queue items to be processed.
        private void WaitForWork()
        {
            SafeWaitHandle handle = _ev.SafeWaitHandle;

            NativeMethods.MSG msg = new NativeMethods.MSG();

            while (true)
            {
                try
                {
                    // pump any messages
                    while (UnsafeNativeMethods.PeekMessage(ref msg, IntPtr.Zero, 0, 0, NativeMethods.PM_REMOVE))
                    {
                        if (msg.message == NativeMethods.WM_QUIT)
                        {
                            break;
                        }
                        Misc.DispatchMessage(ref msg);
                    }

                    // do any work items in the queue
                    // It's possible items could be enqueued between when we check for the count
                    // and dequeue but the event is set then and we'll come back into DrainQueue.
                    // (note: don't use a for loop here because as the counter is incremented
                    // Count is decremented and we'll only process half the queue)
                    while (_q.Count > 0)
                    {
                        // pull an item off the queue, process, then clear it
                        QueueItem item = (QueueItem)_q.Dequeue();

                        item.Process();
                    }

                    int result = Misc.MsgWaitForMultipleObjects(handle, false, NativeMethods.INFINITE, NativeMethods.QS_ALLINPUT);
                    if (result == NativeMethods.WAIT_FAILED || result == NativeMethods.WAIT_TIMEOUT)
                    {
                        Debug.Assert(false, "MsgWaitForMultipleObjects failed while WaitForWork");
                        break;
                    }
                }
                catch (Exception e)
                {
                    if (Misc.IsCriticalException(e))
                    {
                        throw;
                    }

                    // Might happen when if the hwnd goes away between the peek and the dispatch
                }
                //
            }
        }