【问题标题】:Why would Application.Exit fail to work?为什么 Application.Exit 无法工作?
【发布时间】:2010-10-07 22:51:29
【问题描述】:

我有一个应用程序在取消对话框时出现奇怪的错误。如果该框被取消,应用程序将无法继续,因此它会退出,但由于某种原因它无法正常工作,因此它会继续运行并崩溃。

我调试了这个问题,不知何故,应用程序在 Application.Exit 调用之后运行。我在调试模式下运行,这是相关的,因为少量代码取决于定义的 RELEASE 变量。这是我的应用退出代码。我跟踪了代码,它进入了 ExitApp 方法,并继续运行,将控制权返回给调用者并最终崩溃。

这是一个通过远程桌面连接提供报告的应用程序,因此退出代码有点奇怪。它试图终止远程会话,但仅在发布时运行,因为我不想在每次测试运行时关闭我的开发机器。

    private void ExitApp()
    {
        HardTerminalExit();
        Application.Exit();
    }

    // When in Debug mode running on a development computer, this will not run to avoid shutting down the dev computer
    // When in release mode the Remote Connection or other computer this is run on will be shut down.
    [Conditional("RELEASE")]
    private void HardTerminalExit()
    {
        WTSLogoffSession(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, false);
    }

我在 Application.Exit 行之后运行了一个调试器,但没有任何反应,然后在我越过该行后控制权返回给调用者。

发生了什么事?这是一个 Windows 窗体应用程序。

【问题讨论】:

  • 对我来说-我执行了不同的 form.Show() 调用-关闭了该窗口并且 application.exit() 失败,我将其更改为 form.ShowDialog() 调用并且一切都更好

标签: c# .net winforms


【解决方案1】:

这个应用程序是否使用Application.Run() 运行(在Main 方法中)?否则,Application.Exit() 将不起作用。

如果您编写了自己的Main 方法并且想要停止应用程序,则只能通过从Main 方法返回(或终止进程)来停止。

【讨论】:

    【解决方案2】:

    试试Environment.Exit(exitCode)

    【讨论】:

      【解决方案3】:

      这篇文章扩展了您正在经历的同一思路:http://www.dev102.com/2008/06/24/how-do-you-exit-your-net-application/

      基本上:

      • Environment.Exit - 来自 MSDN:终止此进程并提供 底层操作系统 指定的退出代码。这是代码 使用控制台时调用 申请。

      • Application.Exit - 来自 MSDN:通知所有消息泵,它们 必须终止,然后关闭所有 消息后的应用程序窗口 已处理。这是代码 如果您被呼叫,请使用 应用程序运行(WinForms 应用程序),此方法停止所有 在所有线程上运行消息循环 并关闭所有窗口 应用。还有一些 有关此方法的问题,请阅读 它在 MSDN 页面中。

      对此的另一个讨论:http://geekswithblogs.net/mtreadwell/archive/2004/06/06/6123.aspx

      这篇文章指出了一个很好的提示:

      您可以通过检查 System.Windows.Forms.Application.MessageLoop 属性来确定是否已调用 System.Windows.Forms.Application.Run。如果为真,则 Run 已被调用,您可以假设 WinForms 应用程序正在执行,如下所示。

      if (System.Windows.Forms.Application.MessageLoop)
      {
        // Use this since we are a WinForms app
        System.Windows.Forms.Application.Exit();
      }
      else
      {
        // Use this since we are a console app
        System.Environment.Exit(1);
      }
      

      【讨论】:

      • 我在调用 exit 方法后添加了一个额外的 return。这解决了问题。
      • @TonyPeterson 需要这样做的原因是 Exit 调用将 Exit 消息放在队列中,但会继续执行直到应用程序处理退出请求,因此您需要在该点返回结束执行.哇刚刚意识到这有多大了,对不起
      • 嗨@TonyPeterson,您能否发布您添加的“额外退货”的代码?提前非常感谢。
      • 我将代码从仅显示表单更改为通过 Application.Run ReportDisplay rd = new ReportDisplay(u, cd.reports, u.root,emails); Application.Run(rd);
      • Application.Run() 开头的控制台或no forms 消息循环怎么样?我无法杀死野兽,甚至使用方法 () => ThreadExit() 实现自己的 ApplicationContext...
      【解决方案4】:

      我在很多情况下都经历过这种情况,我使用 Thread.CurrentThread.Abort()

      然后进程关闭。 Application.Exit 似乎没有与当前线程正确连接。

      【讨论】:

        【解决方案5】:

        还要确保应用程序中运行的所有线程都将 IsBackground 属性设置为 true。非后台线程很容易阻止应用程序退出。

        【讨论】:

          【解决方案6】:

          确保你没有 Console.ReadLine();在您的应用和 Environment.Exit(1) 中;将工作并关闭您的应用程序。

          【讨论】:

            【解决方案7】:

            最近遇到了这个问题(Application.Exit 未能正确终止带有 Application.Run(new Form()) 的 win-forms 的消息泵),我发现如果您正在生成新线程或在其中启动后台工作人员构造函数,这将阻止 Application.Exit 运行。

            将所有“RunWorkerAsync”调用从构造函数移至表单加载方法:

            public Form()
            {
              this.Worker.RunWorkerAsync();
            }
            

            移至:

            public void Form_Load(object sender, EventArgs e)
            {
              this.Worker.RunWorkerAsync();
            }
            

            【讨论】:

              【解决方案8】:

              试试这个:

              在 Program.cs 文件中:

              Application.Run(new form());

              之后

              添加 Application.Exit();

              【讨论】:

                【解决方案9】:

                我创建了以下内容,它将在任何地方退出应用程序。您不必担心表单是否正在运行,测试会确定并调用适当的 Exit。

                    public void exit(int exitCode)
                    {
                        if (System.Windows.Forms.Application.MessageLoop)
                        {
                            // Use this since we are a WinForms app
                            System.Windows.Forms.Application.Exit()
                        }
                        else
                        {
                            // Use this since we are a console app
                            System.Environment.Exit(exitCode);
                        }
                    } //* end exit()
                

                【讨论】:

                  【解决方案10】:
                      private void frmLogin_FormClosing(object sender, FormClosingEventArgs e)
                      {
                  
                          if (e.CloseReason == CloseReason.UserClosing)
                          {
                              DialogResult result = MessageBox.Show("Do you really want to exit?", "Dialog Title", MessageBoxButtons.YesNo);
                              if (result == DialogResult.Yes)
                              {
                                  Environment.Exit(0);
                              }
                              else
                              {
                                  e.Cancel = true;
                              }
                          }
                          else
                          {
                              e.Cancel = true;
                          }
                  
                  
                      }
                  

                  【讨论】:

                  • 欢迎 Jordan,您能否为您的代码如何帮助回答问题添加上下文?
                  • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。您可以在帮助中心找到更多关于如何写好答案的信息:stackoverflow.com/help/how-to-answer。祝你好运?
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-07-24
                  • 2017-04-23
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多