如何通过程序退出WPF应用程序?

565

当用户从“文件”菜单中点击“退出”菜单项时,如何退出应用程序?

我尝试过:

this.Dispose();
this.Exit();
Application.ShutDown();
Application.Exit();
Application.Dispose();

除了很多其他方法,都没有起作用。

19个回答

898

要退出应用程序,您可以调用

System.Windows.Application.Current.Shutdown();

根据Application.Shutdown方法文档所述,你还可以通过指定ShutdownMode来修改应用程序的关闭行为:

以下情况下,Windows Presentation Foundation (WPF) 会隐式调用 Shutdown:

  • 当 ShutdownMode 设置为 OnLastWindowClose 时。
  • 当 ShutdownMode 设置为 OnMainWindowClose 时。
  • 当用户结束会话并且 SessionEnding 事件未被处理或处理但未取消时。

请注意,Application.Current.Shutdown(); 只能从创建 Application 对象的线程(通常是主线程)中调用。


9
如我所指出的,这并不奇怪。在WPF中,Application是一个静态类,而Application.Current是对当前运行的应用程序的引用。 - TimothyP
4
我认为这有点奇怪,因为乍一看不太明显,而且与以前的模型略有不同,会让人们感到困惑。当然,它的工作原理是完全合理的。 - Brian MacKay
24
如果你调用 Application.Current.Shutdown(); ,你的函数不会立即返回。你还需要调用 return; - Erwin Mayer
2
我使用了这段代码,在其中一个窗口中弹出另一个窗口,然后在那个窗口的window_closed事件中添加了这段代码。所有的窗口都消失了,但程序仍然运行,直到创建弹出窗口之后。 - diyoda_
10
@TimothyP,Application并不是一个静态类。虽然有一个静态成员Application.Current,但这并不意味着它是静态的。相反,它是一个普通的类,可以被继承。 - Earth Engine
显示剩余2条评论

193

如果您真的需要关闭它,您还可以使用Environment.Exit(),但这一点都不优雅(更像是结束进程)。

使用方法如下:

Environment.Exit(0)

5
如果你不关心退出代码,可以使用Environment.Exit(0)。而Environment.Exit()需要至少一个参数,即退出代码。请注意不要改变原意。 - gbmhunter
32
这个方法实际上关闭了所有东西。我的应用程序一直在运行某些东西(虽然窗体已经关闭,但某个进程仍在运行),使用Application.Current.Shutdown();即可解决。 - gbmhunter
5
Environment.Exit是确保关闭应用程序的正确方法。使用Application.Current.Shutdown,如果您有将自己推回调度程序的代码,很容易导致应用程序无限运行。 - Marcus Andrén
和 Application.exit(0); 一样。 - Abdul Saleem
2
使用 Application.Current.Shutdown(); 时,我的 Closing 事件被调用了,但我只是想立即关闭我的应用程序。因此,Environment.Exit(0); 是更好的选择。 - FredM

83
wuminqi 所说,Application.Current.Shutdown(); 是不可逆的,通常用于强制关闭应用程序,例如当用户注销或关闭 Windows 时。 相反,在您的主窗口中调用 this.close()。这与在窗口上按下 Alt + F4 或关闭 [x] 按钮相同。这将导致所有其他所属窗口关闭,并最终调用 Application.Current.Shutdown();,前提是关闭操作没有被取消。请参阅 MSDN 文档中关于关闭窗口的说明。 另外,由于 this.close() 是可取消的,因此可以在关闭事件处理程序中添加保存更改确认对话框。只需为 <Window Closing="..."> 创建事件处理程序,并相应地更改 e.Cancel 即可。(有关如何执行此操作的更多详细信息,请参见MSDN 文档。)

3
我决定选择这个选项,特别是因为我需要在实际退出应用程序之前保存打开的文件。 - AgentKnopf
4
这里需要注意的一件重要事情是:Allen指出了一个非常重要的事实,即所有其他拥有的窗口都将关闭。你必须确保声明所有权。如果你有一个正在运行的窗口,然后打开另一个窗口但还没有显示它,在关闭活动窗口之后,隐藏的窗口将强制应用程序继续运行。除非通过其他方式关闭该窗口(任务管理器等),否则可能会导致潜在的内存泄漏。我已经测试过这个问题。 - B.K.
@B.K. 那么在这种情况下,使用 Application.Current.Shutdown() 而不是 this.close() 会关闭隐藏的窗口吗? - Somanna

40

根据需要使用以下任何一种:

1.

 App.Current.Shutdown();
OR
 Application.Current.Shutdown();

2.

 App.Current.MainWindow.Close();
OR
 Application.Current.MainWindow.Close();

以上所有方法都将调用Window类的closing event,程序可能会在某个点停止执行(因为通常应用程序会在完全关闭窗口之前放置对话框,如'你确定吗?'或'关闭前是否保存数据?')。

3. 但如果你想立即无任何警告地终止应用程序。请使用以下代码:

   Environment.Exit(0);

29

20

这是我做的方式:

// Any control that causes the Window.Closing even to trigger.
private void MenuItemExit_Click(object sender, RoutedEventArgs e)
{
    this.Close();
}

// Method to handle the Window.Closing event.
private void Window_Closing(object sender, CancelEventArgs e)
{
    var response = MessageBox.Show("Do you really want to exit?", "Exiting...",
                                   MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
    if (response == MessageBoxResult.No)
    {
        e.Cancel = true;
    }
    else
    {
        Application.Current.Shutdown();
    }
}

我只在主应用程序窗口中调用 Application.Current.ShutDown(),其它所有窗口使用 this.Close()。在我的主窗口中,Window_Closing(...) 处理右上角的 x 按钮。如果任何一个方法调用关闭窗口,Window_Closing(...) 会在用户确认后获取关闭事件。

事实上,我之所以在我的主窗口中使用 Application.Current.Shutdown() 是因为我注意到,如果在应用程序中没有声明一个窗口的父窗口,那么当该窗口在上一个活动窗口关闭前打开时,我会留下一个隐藏的窗口在后台运行。应用程序将不会关闭。防止完全的内存泄漏的唯一方法是进入任务管理器关闭应用程序。 Application.Current.Shutdown()可以保护我免受意外设计缺陷的影响。

这是我个人的经验。最终,请根据您的情况使用最好的方法。这只是另一个信息。


19

总之,有几种方法可以做到这一点。

1) 杀死进程,跳过终止、错误处理等:

Process.GetCurrentProcess().Kill();

2) 关闭当前应用程序,这可能是正确的方式,因为它调用了退出事件:

Application.Current.Shutdown();
或者
this.Shutdown();

(在App类的实例中调用时)

3)关闭当前应用程序(所有表单必须先关闭/完成):

this.Close(); 

(在App类的实例中调用时)

4) 退出环境,终止应用程序:

Environment.Exit(0);

此外,您可能想阅读有关退出状态的信息在此处


1
"Environment.Exit(0);" 对我有效。得票最高的答案是 "System.Windows.Application.Current.Shutdown();",但它没有起作用,因为应用程序尝试运行下一行代码。我投了你一票。谢谢。 - Ricardo Araújo

17

不应该出现Application.ShutDown();或者.Exit()消息。

Application是一个静态类,它并不指向当前的应用程序。你需要获取当前应用程序并像这样关闭它:

Application.Current.Shutdown();

12

你可以用另一种方式来完成这个任务:

System.Diagnostics.Process.GetCurrentProcess().Kill();

这将强制终止您的应用程序。即使在多线程应用程序中,它也总是有效的。

注意:只要小心不要丢失另一个线程中未保存的数据。


这个似乎不可理解:“'in process always works'”。你能修复它吗?或者至少在评论中解释一下你的意思? - Peter Mortensen
这也部分是不可理解的:只关心一个应用程序,该应用程序从另一个线程中保存数据到文件中。 你能修复它吗?或者至少在评论中解释一下你的意思? - Peter Mortensen
你在使用谷歌翻译吗? - Peter Mortensen
不,我的意思是当应用程序作为多线程运行时,使用Process.Kill会起作用,但是另一种方式,比如this.close,在另一个线程正在运行时在多线程应用程序中不起作用。 - Ali Yousefi

7

请尝试

App.Current.Shutdown();

对于我来说

Application.Current.Shutdown(); 

无法正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,