我有一个用 C# 发布的应用程序。每当我通过单击红色退出按钮关闭主表单时,表单会关闭,但不会关闭整个应用程序。我在尝试关闭计算机时发现了这一点,随后被许多带有我添加的 MessageBox
警报的子窗口轰炸。
我试过 Application.Exit
但它仍然调用所有子窗口和警报。我也不知道如何使用 Environment.Exit
以及将哪个整数放入其中。
此外,每当我的表单调用 FormClosed
或 FormClosing
事件时,我都会使用 this.Hide()
函数关闭应用程序;这会影响我的应用程序的行为吗?
来自 MSDN:
通知所有消息泵它们必须终止,然后在处理完消息后关闭所有应用程序窗口。如果您已调用 Application.Run(WinForms 应用程序),这是要使用的代码,此方法会停止所有线程上所有正在运行的消息循环并关闭应用程序的所有窗口。
终止此进程并为底层操作系统提供指定的退出代码。这是您使用控制台应用程序时要调用的代码。
这篇文章 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?
我知道这不是您遇到的问题,但是可能发生这种情况的另一个原因是您在应用程序中打开了一个非后台线程。
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);
}
}
}
}
当 IsBackground
为 false
时,它将保持程序打开直到线程完成,如果您将 IsBackground
设置为 true
,线程将不会保持程序打开。 BackgroundWoker
、ThreadPool
和 Task
之类的东西都在内部使用 IsBackground
设置为 true
的线程。
顺便一提。每当我的表单调用 formclose 或表单关闭事件时,我都会使用 this.Hide() 函数关闭应用程序。这会影响我的应用程序现在的行为吗?
简而言之,是的。当主窗体(通过 Main
方法中的 Application.Run
启动的窗体)关闭(未隐藏)时,整个应用程序将结束。
如果您的整个应用程序在主窗体关闭时始终完全终止,那么您应该删除该窗体关闭处理程序。通过不取消该事件并在用户关闭它时让它们关闭,您将获得所需的行为。至于所有其他表单,如果您不打算再次显示相同的表单实例,您只需让它们关闭,而不是阻止关闭并隐藏它们。如果您再次显示它们,那么隐藏它们可能没问题。
如果您希望能够让用户为您的主表单单击“x”,但让另一个表单保持打开状态并且实际上成为“新”主表单,那么它会有点复杂。在这种情况下,您只需要隐藏您的主窗体而不是关闭它,但是您需要添加某种机制,当您确实希望您的应用程序结束时,它实际上会关闭主窗体。如果这是您所处的情况,那么您需要在问题中添加更多详细信息,描述哪些类型的应用程序应该和不应该实际结束程序。
在这种情况下,退出应用程序的最正确方法是覆盖 App.xaml.cs 中的 onExit() 方法:
protected override void OnExit(ExitEventArgs e) {
base.OnExit(e);
}
Application.Exit()
无法退出应用程序,但Environment.Exit(1)
就像一个魅力。Environment.Exit(0)
任何非零值都是特定于应用程序的错误代码,脚本可以使用它来采取适当的操作。 (这是新代码和 WinForms 应用程序,因此在这种情况下不太重要,但对于任何编写命令行工具的人来说都很好。)Environment.Exit
也可用于表单应用程序。return
声明会大大改进这种方法。据我了解,代码将在Application.Exit()
之后继续执行,直到return
语句。