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


196

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

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

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


2
不处理FormClosed或FormClosing
断线

1
因此,您说您只是隐藏表单而不是关闭表单?这可能是应用程序不终止的原因,它仍然具有开放(隐藏)的形式。
Xint0 2012年

然后我应该将所有this.Hide()替换为this.Close()?
约翰·欧内斯特·瓜达卢佩

1
您不需要Hide()或Close()。
Henk Holterman

1
发布有关关闭动作和事件的代码。
Henk Holterman

Answers:


329

从MSDN:

申请退出

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

环境出口

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

本文Application.Exit与Environment.Exit指向一个很好的提示:

您可以System.Windows.Forms.Application.Run通过检查System.Windows.Forms.Application.MessageLoop属性来确定是否已调用。如果为true,则已调用Run,并且可以假定WinForms应用程序正在按以下方式执行。

if (System.Windows.Forms.Application.MessageLoop) 
{
    // WinForms app
    System.Windows.Forms.Application.Exit();
}
else
{
    // Console app
    System.Environment.Exit(1);
}

参考:为什么Application.Exit无法正常工作?


这对我真的很有用,因为我有一个WinForms应用程序,该应用程序有一个参数,因此它可以静默运行,因此不显示表单。当表单被隐藏后,便Application.Exit()无法退出应用程序,但是却Environment.Exit(1)像是一种魅力。
Dib

5
问题没有提到由于错误而退出,因此退出代码应为零:Environment.Exit(0) 任何非零值都应是特定于应用程序的错误代码,脚本可以使用该错误代码采取适当的措施。(这是新代码和WinForms应用程序,因此在这种情况下不大可能,但是对于编写命令行工具的任何人都应该知道。)
YipYip

Environment.Exit也可以用于表单应用程序。
Badiparmagi

1
如果我错了,请纠正我,但我认为return事后声明可以大大改善这种方法。正如我理解的代码会后继续执行Application.Exit(),直到一个return声明。
Bighted19

17

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

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它将使您的程序保持打开状态,直到线程完成;如果设置IsBackgroundtrue线程,则将不会使程序保持打开状态。之类的东西BackgroundWokerThreadPoolTask所有的内部使用一个线程与IsBackground设置为true


14

所有你需要的是 System.Environment.Exit(1);

它使用系统命名空间“使用系统”,该名称空间在启动项目时几乎总是存在。


2
它仅适用于控制台应用程序。
Nidhin David

需要注意的一件事是,不会为Environment调用FormClosing / FormClosed事件。退出ExitCode仅应在发生错误时为非零,
Raphael Smit

9

我会选择以下其中一项:

Application.Exit();

对于winform或

Environment.Exit(0);

用于控制台应用程序(也适用于winforms)。

谢谢!


Environment.Exit(0)也适用于WinForms,存在该应用程序而不会引发任何异常。
MulleOne

8

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

简而言之,是的。当主形式(通过启动的形式整个应用程序将结束Application.RunMain方法)被关闭(不隐藏)。

如果您的整个应用程序总是在关闭主窗体时始终完全终止,那么您应该删除该窗体的关闭处理程序。通过不取消该事件而仅在用户关闭事件时让它们关闭,您将获得所需的行为。至于所有其他表单,如果您不想再次显示该表单的同一实例,则只需让它们关闭即可,而不是防止关闭和隐藏它们。如果您再次显示它们,则隐藏它们可能很好。

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


3

你会做:

Application.Run(myForm);

在您的Main()中?

我发现关闭表单时杀死应用程序是一种非常简单的方法。


1
是的,它确实在Main的Program.cs文件中具有Application.Run。那我该怎么做才能关闭它?
约翰·欧内斯特·瓜达卢佩

但是您确实将主表单传递给了Run,对吗?该表格您关闭通过点击红色的X
LightStriker

是的,我有。就像这样:Application.Run(new Form2());
约翰·欧内斯特·瓜达卢佩

在这种情况下,如果传递给Run的主窗体确实完全关闭,则应用程序将自动退出。然后,您必须跟踪该表单为何仍处于打开,运行或隐藏状态的原因。
LightStriker 2012年


-4

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

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

这样,您可以在退出事件发生时执行代码,但实际上并不会导致退出事件发生。
jpaugh
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.