none
Invisible WPF dialog filling up windows message queue?

    Question

  • For legacy reasons we have a native C++ component that needs to create a WPF dialog.  To do this, we created a managed wrapper that creates a thread with ApartmentState.STA and on this thread does the following:

    1. create the WPF dialog but do not display it - only the constructor runs
    2. In a loop:
    3.     block using WaitHandle.WaitOne() until an event is set to trigger showing of the dialog
    4.     call ShowDialog()

    Interestingly, when the application ran for a long time (1 hour or so), the ShowDialog() would cause an exception

     An unhandled exception of type 'System.ComponentModel.Win32Exception' occurred in PresentationFramework.dll

     Additional information: Not enough quota is available to process this command

            at MS.Win32.UnsafeNativeMethods.PostMessage(HandleRef hwnd, Int32 msg, IntPtr wparam, IntPtr lparam)
            at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean enableRenderTarget, Nullable`1 channelSet)
            at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean enableRenderTarget)
            at System.Windows.Interop.HwndTarget.UpdateWindowPos(IntPtr lParam)
            at System.Windows.Interop.HwndTarget.HandleMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
            at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
            at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
            at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
            at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
            at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
            at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
            at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
            at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
            at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
            at MS.Win32.UnsafeNativeMethods.SetWindowPos(HandleRef hWnd, HandleRef hWndInsertAfter, Int32 x, Int32 y, Int32 cx, Int32 cy, Int32 flags)
            at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
            at System.Windows.Window.CreateSourceWindowImpl()
            at System.Windows.Window.SafeCreateWindow()
            at System.Windows.Window.ShowHelper(Object booleanBox)\r\n   at System.Windows.Window.Show()
            at System.Windows.Window.ShowDialog()
            …

            ErrorCode:         0x80004005
            nativeErrorCode:            0x00000718
            _COMPlusExceptionCode:         0xe0434f4d

    After a lot of digging around and experimentation with a small sample app we came to the following conclusions:

    I tested this theory using a suggestion found in http://social.msdn.microsoft.com/forums/en-US/clr/thread/835db88e-db51-4f83-bd4f-a10d126effa6 by replacing "waitHandle.WaitOne()" with

        while (!waitHandle.WaitOne(1000, false));

    to ensure regular message pumping.  (The WaitOne is only responsible for the dialogs message pump while it is invisible, so a frequency of 1 second seemed sufficient.  A cleaner solution would probably be something like "MsgWaitForMultipleObjectEx()" and implementing our own message pump.)

    What we do not understand is the following: Why does a windows message queue get filled up?

    The WPF dialog has only been constructed, ShowDialog has not yet been called, the STA thread is not used for any other operations, but still something seems to be pusing messages into its queue.

    Is there something in WPF that we are should be aware of?

    Andreas

    Friday, June 10, 2011 2:30 PM

Answers