如何关闭在不同线程上运行多个窗口的 WPF 应用程序?

Posted

技术标签:

【中文标题】如何关闭在不同线程上运行多个窗口的 WPF 应用程序?【英文标题】:How do I close a WPF application with multiple windows running on separate threads? 【发布时间】:2016-07-26 00:44:21 【问题描述】:

我正在开发一个 WPF 应用程序,当主窗口关闭时我需要完全关闭它。还有另外一个窗口可以被我这样打开运行的程序打开(变量名改了,但这里是逻辑):

private void NewWindowButton_Click(object sender, RoutedEventArgs e) 
    Thread WindowThread = new Thread(new ThreadStart(NewWindowThread));
    WindowThread.SetApartmentState(ApartmentState.STA);
    WindowThread.IsBackground = true;
    WindowThread.Start();


private void NewWindowThread() 
    var NewWindow = new NewWindow();
    NewWindow.Show();
    Dispatcher.Run();

当主窗口关闭时,我让关闭事件调用应用程序关闭方法,如下所示:

private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
    Application.Current.Shutdown();

这会关闭在与主窗口相同的线程中创建的所有窗口,但这不会关闭我在新线程中打开的其他窗口。如何确保在主窗口关闭时我的所有窗口都关闭?

编辑:链接的帖子仅部分回答了我的问题。使用函数Environment.Exit(0); 可以关闭每个窗口,但它会导致我的所有窗口在单击 X 按钮后关闭大约 2-3 秒,而 Application.Current.Shutdown(); 会立即关闭窗口但让其他线程保持打开状态。调用 Shutdown 后,同一个线程上没有任何事情发生,因此我不需要在它之后使用 return 语句。

【问题讨论】:

这个? How to exit a WPF app programmatically? 我尝试使用 Environment.Exit(0); 并且它可以工作,但现在程序需要大约 2-3 秒才能关闭,而不是像使用 Application.Current.Shutdown(); 那样立即发生。 让主窗口保持所有打开的子窗口的集合,并在完成关闭顺序时关闭所有子窗口。 这可能是我必须做的。当它的窗口关闭时,运行我的单独窗口的新线程会被终止吗? 您的代码有效,如果您在 MainWindow 上单击 X,那么所有窗口也会关闭。 【参考方案1】:

您可以将项目属性中的 ShutdownMode 更改为在 MainWindow 关闭时关闭。在您的“Application.xaml”文件中更改

ShutdownMode="OnLastWindowClose"

ShutdownMode="OnMainWindowClose"

【讨论】:

【参考方案2】:

我自己想出了一种方法,无需调用Environment.Exit(0);,而是创建一个线程列表,然后调用线程调度程序的 InvokeShutdown 方法。这是上面修改后的代码:

private List<Thread> threadList = new List<Thread>();

private void NewWindowButton_Click(object sender, RoutedEventArgs e) 
    Thread WindowThread = new Thread(new ThreadStart(NewWindowThread));
    threadList.Add(WindowThread);
    WindowThread.SetApartmentState(ApartmentState.STA);
    WindowThread.IsBackground = true;
    WindowThread.Start();


private void NewWindowThread() 
    var NewWindow = new NewWindow();
    NewWindow.Show();
    Dispatcher.Run();


private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)

    foreach (Thread thread in threadList)
    
        Dispatcher.FromThread(thread).InvokeShutdown();
    
    Application.Current.Shutdown();

这会导致单独线程中的所有窗口在主窗口关闭时关闭,并且不会像 Environment.Exit(0); 那样导致任何延迟。

【讨论】:

以上是关于如何关闭在不同线程上运行多个窗口的 WPF 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

关于C# WPF线程后台运行的

具有多个视图的 WPF 桌面应用程序

如何在 IronPython 中关闭 WPF 窗口而不关闭 .NET 应用程序

使用 Catel 创建多个 WPF 应用程序

WPF关闭应用汇总

如何在 WPF 中从一个窗口移动到另一个窗口?