如何正确退出 C# 应用程序?

Posted

技术标签:

【中文标题】如何正确退出 C# 应用程序?【英文标题】:How do I properly exit a C# application? 【发布时间】:2012-10-10 06:50:20 【问题描述】:

我有一个用 C# 发布的应用程序。这里的问题是每当我通过单击红色退出按钮关闭主表单时,它会关闭表单但不会关闭应用程序。我在尝试关闭计算机时发现了这一点,希望我制作的应用程序运行顺利,然后我被很多子窗口轰炸了,我用这些子窗口设置了MessageBox Alerts。

我尝试了Application.Exit,但它仍然调用所有子窗口和警报,我不知道如何使用Environment.Exit 以及将哪个整数放入其中。

顺便说一句,每当我的表单调用formclosedform closing 事件时,我都会使用this.Hide() 函数关闭应用程序;这会影响我的应用程序现在的行为吗?

【问题讨论】:

不处理 FormClosed 或 FormClosing 所以你说你只是隐藏表单而不是关闭它们?这可能是应用程序没有终止的原因,它仍然有打开(隐藏)的表单。 那我应该把所有的this.Hide()替换成this.Close()? 你不需要 Hide() 或 Close()。 贴出有关关闭动作和事件的代码。 【参考方案1】:

在这种情况下,退出应用程序的最正确方法是覆盖 App.xaml.cs 中的 onExit() 方法:

protected override void OnExit(ExitEventArgs e) 
    base.OnExit(e); 

【讨论】:

这允许您在退出事件发生时执行代码,但实际上不会导致退出事件发生。【参考方案2】:

我知道这不是您遇到的问题,但是可能发生这种情况的另一个原因是您的应用程序中打开了一个非后台线程。

using System;
using System.Threading;
using System.Windows.Forms;

namespace Sandbox_Form

    static class Program
    
        private static Thread thread;

        [STAThread]
        static void Main()
        
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            thread = new Thread(BusyWorkThread);
            thread.IsBackground = false;
            thread.Start();

            Application.Run(new Form());

        

        public static void BusyWorkThread()
        
            while (true)
            
                Thread.Sleep(1000);
            
        
    

IsBackgroundfalse 时,它将保持程序打开直到线程完成,如果将IsBackground 设置为true,线程将不会保持程序打开。诸如BackgroundWokerThreadPoolTask 之类的东西都在内部使用IsBackground 设置为true 的线程。

【讨论】:

【参考方案3】:

来自 MSDN:

Application.Exit

通知所有消息泵它们必须终止,然后在处理完消息后关闭所有应用程序窗口。如果您已调用 Application.Run(WinForms 应用程序),这是要使用的代码,此方法会停止所有线程上所有正在运行的消息循环并关闭应用程序的所有窗口。

Environment.Exit

终止此进程并为底层操作系统提供指定的退出代码。这是您在使用控制台应用程序时要调用的代码。

这篇文章Application.Exit vs. Environment.Exit指出了一个很好的提示:

您可以通过检查System.Windows.Forms.Application.MessageLoop 属性来确定是否已调用System.Windows.Forms.Application.Run。如果为真,则 Run 已被调用,您可以假设 WinForms 应用程序正在执行,如下所示。

if (System.Windows.Forms.Application.MessageLoop) 

    // WinForms app
    System.Windows.Forms.Application.Exit();

else

    // Console app
    System.Environment.Exit(1);

参考:Why would Application.Exit fail to work?

【讨论】:

这对我来说非常有用,因为我有一个 WinForms 应用程序,它有一个参数,因此它可以静默运行,因此不显示表单。当表单被隐藏时,Application.Exit() 无法退出应用程序,但是 Environment.Exit(1) 就像一个魅力。 问题没有提到由于错误而退出,因此退出代码应该为零:Environment.Exit(0) 任何非零值都意味着可以使用特定于应用程序的错误代码通过脚本采取适当的行动。 (这是新代码和 WinForms 应用程序,因此在这种情况下不太重要,但对于任何编写命令行工具的人来说都很好。) Environment.Exit 也可以用于表单应用。 如果我错了,请纠正我,但我认为之后的return 声明会大大改进这种方法。据我了解,代码将在Application.Exit() 之后继续执行,直到出现return 语句。【参考方案4】:

顺便说一句。每当我的表单调用 formclose 或表单关闭事件时,我都会使用 this.Hide() 函数关闭应用程序。这会影响我的应用程序现在的行为吗?

简而言之,是的。当主窗体(在Main 方法中通过Application.Run 启动的窗体)关闭(未隐藏)时,整个应用程序将结束。

如果您的整个应用程序在主窗体关闭时始终完全终止,那么您应该删除该窗体关闭处理程序。通过不取消该事件并在用户关闭它时让它们关闭,您将获得所需的行为。至于所有其他表单,如果您不打算再次显示相同的表单实例,您只需让它们关闭,而不是阻止关闭并隐藏它们。如果您再次显示它们,那么隐藏它们可能没问题。

如果您希望能够让用户单击主窗体的“x”,但让另一个窗体保持打开状态,并且实际上成为“新”主窗体,那么它会稍微复杂一些。在这种情况下,您只需要隐藏主窗体而不是关闭它,但是您需要添加某种机制,当您确实想要您的主窗体时实际上关闭主窗体应用程序结束。如果您遇到这种情况,那么您需要在问题中添加更多详细信息,描述哪些类型的应用程序应该和不应该实际结束程序。

【讨论】:

以上是关于如何正确退出 C# 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

C# 退出程序方法

c# winform程序 如何判断用户输入的验证码是不是正确?

C# WinForm程序中强制退出程序以及启动程序

如何对从 C# 应用程序中退出的指令进行采样

c#多线程

如何从另一个进程捕获退出代码[重复]