Question

Description

Hi, I've been searching the web for information on this and didn't find anything that would lead to it being fixed.

I want to show a dialog when my main window loads and thus I assigned an event handler to my MainWindow's Loaded event. The handler is as follows:

private void Window_Loaded(object sender, RoutedEventArgs e) {
    if (Settings.Instance.GetBool(ConfigFunctionalityGroup, "CheckForUpdatesOnStartup")) {
        worker = new BackgroundWorker();
        worker.DoWork += worker_DoWork;
        worker.ProgressChanged += worker_ProgressChanged;
        worker.WorkerReportsProgress = true;
        worker.RunWorkerAsync();
    }

    findandreplacedialog = new FindAndReplaceDialog() { Owner = this };

    Open_Environment_Click(null, null);
}

Open_Environment_Click is an event handler for a menu item, and is written as follows:

private void Open_Environment_Click(object sender, RoutedEventArgs e) {
    SelectEnvironmentDialog dialog = new SelectEnvironmentDialog(Environments);

    if (dialog.ShowDialog().Value == true) {
        dialog.SelectedEnvironment.Open();
    }
}

Exception

The exception occurs when I call the ShowDialog of dialog in Open_Environment_Click.

The details on the exception are as follows:

    System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Cannot perform this operation while dispatcher processing is suspended.
  Source=WindowsBase
  StackTrace:
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Window.ShowHelper(Object booleanBox)
       at System.Windows.Window.Show()
       at System.Windows.Window.ShowDialog()
       at UnrealSed.MainWindow.Open_Environment_Click(Object sender, RoutedEventArgs e) in c:\Users\ZéLuís\Documents\Visual Studio 2012\Projects\Unreal Sed\UnrealSed\MainWindow.xaml.cs:line 610
       at UnrealSed.MainWindow.Window_Loaded(Object sender, RoutedEventArgs e) in c:\Users\ZéLuís\Documents\Visual Studio 2012\Projects\Unreal Sed\UnrealSed\MainWindow.xaml.cs:line 89
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
       at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
       at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
       at MS.Internal.LoadedOrUnloadedOperation.DoWork()
       at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
       at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
       at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
       at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
       at System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget)
       at System.Windows.Interop.HwndTarget.OnResize()
       at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage 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, Int32 numArgs)
       at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.HwndSubclass.DefWndProcWrapper(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
  InnerException: 

Further Details

The interesting part is that I do not get the error when I call Show on a new window inside the MainWindow's constructor, maintaining the above code (just adding this line in the constructor):

new GotoDialog().Show();

Note that I did not shorten any of the code provided, ShowDialog is not custom and not opening the window on Loaded but from the menu works.

Was it helpful?

Solution

You are probably hitting this snag because the code calls ShowDialog while WPF is busy calculating layout. During layout dispatcher processing is suspended, which means that no window manager messages can be processed (and therefore you can't show a dialog, because doing that relies on messages being processed).

Normally the solution to this is to simply schedule the operation (in this instance, ShowDialog) for whenever it's possible with something like

Dispatcher.CurrentDispatcher.BeginInvoke((Action)(...));

However, you can't do that here because you want the result of the dialog to be provided synchronously. And you can't use Invoke because that would either throw or deadlock (I haven't tried it).

You can BeginInvoke the call to Open_Environment_Click as a whole though:

Dispatcher.CurrentDispatcher.BeginInvoke(
    new Action(() => Open_Environment_Click(null, null)));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top