2

描述

你好,我一直在网上搜索这方面的信息,但没有找到任何可以修复它的东西。

我想在我的主窗口加载时显示一个对话框,因此我为我MainWindow的 Loaded 事件分配了一个事件处理程序。处理程序如下:

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是菜单项的事件处理程序,编写如下:

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

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

例外

当我在中调用ShowDialogof 对话框时发生异常Open_Environment_Click

异常详情如下:

    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: 

更多细节

有趣的是,当我在 's 的构造函数中的新窗口上调用 Show 时,我没有收到错误MainWindow,维护上面的代码(只需在构造函数中添加这一行):

new GotoDialog().Show();

请注意,我没有缩短提供的任何代码,ShowDialog不是自定义的,也不是打开窗口Loaded而是从菜单工作。

4

1 回答 1

5

您可能遇到了这个问题,因为ShowDialog当 WPF 忙于计算布局时代码调用。在布局调度程序处理暂停期间,这意味着不能处理任何窗口管理器消息(因此您不能显示对话框,因为这样做依赖于正在处理的消息)。

通常,解决这个问题的方法是简单地安排操作(在这种情况下,ShowDialog),只要有可能,就可以使用类似的东西

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

但是,您不能在此处执行此操作,因为您希望同步提供对话框的结果。而且你不能使用Invoke,因为那会抛出或死锁(我没有尝试过)。

您可以整体BeginInvoke调用:Open_Environment_Click

Dispatcher.CurrentDispatcher.BeginInvoke(
    new Action(() => Open_Environment_Click(null, null)));
于 2013-02-25T12:28:02.607 回答