我有一个用 C# 发布的应用程序。每当我通过单击红色退出按钮关闭主窗体时,窗体都会关闭,但不会关闭整个应用程序。当我尝试关闭计算机时我发现了这一点,随后被大量带有我添加的
MessageBox
警报的子窗口轰炸。
我尝试了
Application.Exit
,但它仍然调用所有子窗口和警报。我不知道如何使用 Environment.Exit
以及要放入哪个整数。
此外,每当我的表单调用
FormClosed
或 FormClosing
事件时,我都会使用 this.Hide()
函数关闭应用程序;这会影响我的应用程序的行为吗?
来自 MSDN:
通知所有消息泵必须终止,然后在处理消息后关闭所有应用程序窗口。如果您调用了 Application.Run(WinForms 应用程序),则使用此代码,此方法会停止所有线程上正在运行的所有消息循环并关闭应用程序的所有窗口。
终止此进程并向底层操作系统提供指定的退出代码。这是当您使用控制台应用程序时要调用的代码。
这篇文章,Application.Exit vs.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);
}
我知道这不是您遇到的问题,但是发生这种情况的另一个原因是您的应用程序中打开了一个非后台线程。
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() 函数关闭应用程序。这会影响我的应用程序现在的行为吗?
简而言之,是的。 当主窗体(通过
Application.Run
方法中的 Main
启动的窗体)关闭(不隐藏)时,整个应用程序将结束。
如果您的整个应用程序在主表单关闭时始终完全终止,那么您应该删除该表单关闭处理程序。 通过不取消该事件并在用户关闭事件时让它们关闭,您将获得所需的行为。 对于所有其他表单,如果您不打算再次显示该表单的同一实例,您只需让它们关闭即可,而不是阻止关闭并隐藏它们。 如果您再次显示它们,那么隐藏它们可能没问题。
如果您希望用户能够单击主窗体的“x”,但让另一个窗体保持打开状态,并实际上成为“新”主窗体,那么情况会稍微复杂一些。 在这种情况下,您需要隐藏主窗体而不是关闭它,但是您需要添加某种机制,当您确实希望应用程序结束时,该机制将“实际上”关闭主窗体。 如果您遇到这种情况,那么您需要在问题中添加更多详细信息,描述哪些类型的应用程序应该或不应该实际结束程序。
this.Close();
或
System.Environment.Exit(1);
private void BudgetMain_Exit(object sender, EventArgs e)
{
DialogResult dialogResult = MessageBox.Show("Are You Sure You Want to
Exit?", "Warning", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
Application.Exit();
}
}
Environment.Exit(0); //0 is exit status
protected override void OnExit(ExitEventArgs e) {
base.OnExit(e);
}