【问题标题】:Whats the difference between these methods for closing my application?这些关闭我的应用程序的方法有什么区别?
【发布时间】:2010-08-27 13:13:13
【问题描述】:

基本上,我有一个主窗体,在加载时会打开一个子窗体以供用户登录。当他们取消或关闭此登录表单时,我需要关闭整个应用程序。

但似乎有几种不同的方法可以关闭 C# 程序:

  1. Application.Exit();

  2. Application.ExitThread();

  3. Environment.Exit(1);

  4. Process.GetCurrentProcess().Kill();

  5. SFTPClient.LDAPLoggedIn = false; Close();

编辑:对不起,如果这个不清楚:它在控制器对象中设置一个属性以指示登录失败。打开子窗体后,我会检查父窗体中的这个属性,看看程序是否应该继续。它基本上将退出程序的责任毫无例外地转移给了父级。

6:throw new Exception("User closed the form");

我可以看到有两种处理方式:

  • 通知家长出现问题(如 5 和 6 中所示)。
  • 从子窗体关闭程序。

这两个中的任何一个被认为是更好的做法吗?

每种方法似乎对我的程序都有相同的效果,但它们的实际比较如何?

更新: 感谢您的回答。对于那些在未来搜索这个问题的人和好奇的人,这是我最终的解决方案:

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 会自动设置为 Cancel,所以我需要做的就是 Close()

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    如果您想在最后一种情况下优雅地处理异常,那ok(虽然不是很好) - 只要它是您的应用程序的异常情况。否则,我将创建一个新方法,将表单显示为带有布尔值的对话框。如果布尔值返回 false(也就是用户关闭了表单),我将处理从那里关闭的应用程序(使用 Application.Exit())。

    在我看来,从孩子那里关闭应用程序而不是告诉父母是非常糟糕的做法。我唯一同意这一点是在FailFast 的情况下,这种情况非常罕见。


    此方法停止所有线程上所有正在运行的消息循环并关闭应用程序的所有窗口。此方法不会强制应用程序退出。 Exit 方法通常在消息循环中调用,并强制 Run 返回。要仅退出当前线程的消息循环,请调用 ExitThread。

    见上文。


    终止此进程并为底层操作系统提供指定的退出代码。


    Kill 强制终止进程,而 CloseMainWindow 只请求终止。当一个带有图形界面的进程正在执行时,它的消息循环处于等待状态。每次操作系统向进程发送 Windows 消息时,都会执行消息循环。


    • SFTPClient.LDAPLoggedIn = false; Close();

    在注释中澄清之后(将流程传递回父级并从那里处理),这是迄今为止最好的方法。


    • throw new Exception("User closed the form");

    向调用进程抛出异常。如果这是主线程,它会以非常丑陋的方式抛出异常。

    【讨论】:

    • 抱歉 - 澄清 #5。它在控制器对象中设置一个属性以指示登录失败。打开子窗体后,我会检查父窗体中的这个属性,看看程序是否应该继续。它基本上将退出程序的责任无一例外地转移给了父级。
    • @rmx - 毫无疑问,肯定是第 5 名。
    【解决方案2】:

    所有这些终止应用程序的方法都太复杂了,它们在不同的场景中很有用,但在你的场景中却没有。

    您可以稍微重新设计您的应用程序,以更优雅的方式解决您的问题。在主方法中,您可能会显示登录表单,如果用户单击“取消”按钮,那么您只需退出主方法。否则,您将显示主要形式:

    class Program {
      static void Main(String[] args) {
         if ( Login.Show() ) {
            //Show main form for your application
         }
         //otherwise you simply return from Main method
      }
    }
    

    这种行为更加清晰和简单。而且在大多数情况下,主窗体过于繁重,因此您的用户应该等待更多时间才能从您的应用中看到第一个窗口。

    【讨论】:

      【解决方案3】:

      您应该使用Form.Close() 而不是Application.Exit。正如 MSDN 文档所述,Form.CloseForm.Closing 等事件在您使用 Application.Exit 时不会触发。

      【讨论】:

      • 好的,我可以看到这样做的好处。那么在每个表单都为Close d 之后,是否应该从 Program.cs 调用Application.Exit
      • 没有理由。如果您退出子线程并且您的主函数返回(结束主线程),您的进程将结束。如果您想提供启动您的进程可能感兴趣的返回码,请在主函数末尾使用Environment.Exit(retcode)
      【解决方案4】:

      感谢 OP 的解决方案,只是想补充一下。

      要关闭您的子窗体并向父级返回 Cancel 以外的其他内容:

      this.DialogResult = DialogResult.OK;
      this.Close();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-14
        • 1970-01-01
        • 1970-01-01
        • 2018-04-29
        • 2012-12-06
        • 1970-01-01
        • 2013-06-14
        相关资源
        最近更新 更多