基本上我有一个主表单,在加载时打开一个子表单以登录用户。当他们取消或关闭此登录表单时,我需要关闭整个应用程序。
但似乎有几种不同的方法可以关闭C#程序:
Application.Exit();
Application.ExitThread();
Environment.Exit(1);
Process.GetCurrentProcess().Kill();
SFTPClient.LDAPLoggedIn = false; Close();
编辑:很抱歉,如果这个不清楚:它在控制器对象中设置一个属性,表明登录失败。打开子表单后,我会在父表单中检查此属性以查看程序是否应该继续。它基本上将退出程序的责任转移给了父母,没有例外。
6:throw new Exception("User closed the form");
我可以看到有两种方法可以处理它:
这两种中的任何一种都被认为是更好的做法吗?
每种方法似乎对我的程序都有相同的影响,但它们实际上是如何比较的?
更新 谢谢你的回答。对于那些在未来和好奇的人中搜索这个问题的人来说,这最终是我的解决方案:
private void FormMain_Load(object sender, EventArgs e)
{
if (new FormLogin().ShowDialog(this) == DialogResult.Cancel) Close();
}
和
private void buttonCancel_Click(object sender, EventArgs e)
{
Close();
}
我发现当通过单击“X”关闭表单时,DialogResult会自动设置为“取消”,所以我需要做的就是Close()
答案 0 :(得分:12)
如果你想在最后一种情况下优雅地处理异常,那就是 ok (虽然不是很好) - 只要它是你的应用程序的特殊情况。否则,我会创建一个新方法,将表单显示为带有布尔值的对话框。如果布尔值返回false(也就是说,用户关闭了表单),那么我将从那里处理关闭的应用程序(使用Application.Exit()
)。
在我看来,从儿童关闭申请而不是告诉父母,这是非常糟糕的做法。我唯一同意这一点的情况是FailFast
,这种情况非常罕见。
此方法停止所有线程上的所有正在运行的消息循环,并关闭应用程序的所有窗口。此方法不会强制应用程序退出。 Exit方法通常在消息循环中调用,并强制Run返回。要仅退出当前线程的消息循环,请调用ExitThread。
见上文。
终止此过程并为底层操作系统提供指定的退出代码。
Kill强制终止进程,而CloseMainWindow仅请求终止。当正在执行具有图形界面的进程时,其消息循环处于等待状态。每次操作系统将Windows消息发送到进程时,都会执行消息循环。
SFTPClient.LDAPLoggedIn = false; Close();
在评论中澄清之后(将流程传递给父级并从那里处理),这是迄今为止最好的方法。
throw new Exception("User closed the form");
抛出调用进程的异常。如果这是主线程,它将以非常丑陋的方式抛出异常。
答案 1 :(得分:4)
终止应用程序的所有这些方法都太复杂了,它们在不同的场景中很有用,但不适用于你的场景。
您可能会稍微重新设计您的应用程序,以更优雅的方式解决您的问题。在main方法中,您可以显示登录表单,如果用户单击“取消”按钮,则只需退出main方法即可。否则你会告诉你主要形式:
class Program {
static void Main(String[] args) {
if ( Login.Show() ) {
//Show main form for your application
}
//otherwise you simply return from Main method
}
}
这种行为更加清晰简单。在大多数情况下,主要形式太重量级,因此您的用户应该等待更多时间从您的应用程序中查看第一个窗口。
答案 2 :(得分:2)
您应该使用Form.Close()
而不是Application.Exit
。正如MSDN文档所述,当您使用Application.Exit
时,Form.Close
和Form.Closing
等事件不会触发。
答案 3 :(得分:1)
感谢OP提供的解决方案,只是想加入它。
关闭您的子表单并将除Cancel之外的内容返回给父表单:
this.DialogResult = DialogResult.OK;
this.Close();