【问题标题】:C# Perform one last action on application crashC# 对应用程序崩溃执行最后一项操作
【发布时间】:2017-01-24 20:23:17
【问题描述】:

我不确定是否有合适的术语来表示我想要的东西,因为我在 google 中尝试过的任何东西都没有买任何东西。

基本上,在应用程序崩溃时,我想执行最后一个操作来清理数据库记录锁定。

我还想在使用停止按钮停止调试时捕捉到这一点,据我了解,使用停止按钮与通过应用程序中的正常进程退出应用程序非常不同。

是否有正常的方法来实现我想要做的事情?该应用程序是用 VS2008 编写的 C#、.NET 3.5 Windows 窗体应用程序。

干杯

【问题讨论】:

    标签: c# exception


    【解决方案1】:

    进程被杀死后,你不能在进程中做任何事情。

    实现您想要的唯一方法是让第二个进程监视第一个进程死亡,然后代表它进行清理。

    您必须担心第二个进程崩溃或被杀死等等。让它适用于所有可能的情况并不容易,但总比没有好。

    【讨论】:

      【解决方案2】:

      检查Handling end process of a windows app 上的任何解决方案是否对您有帮助。

      【讨论】:

        【解决方案3】:

        我认为当用户通过调试器停止进程时无法捕获,但是,您可以覆盖 OnUnhandledException 事件以捕获任何异常被引发但未被应用程序捕获的情况。

        【讨论】:

          【解决方案4】:

          您的第一个要求的答案是拥有(最基本的):

          try
          {
              // Main application
          }
          catch // Though you might not want this
          {
          }
          finally
          {
              // This code always executed even if application crashes.
          }
          

          但是,正如 RichardOD 在他的 cmets 中指出的那样,在处理 Windows 应用程序时还有其他注意事项 - http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx 和这里 http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx

          您的第二个要求的答案是不,您不能在调试器中捕获正在停止的应用程序(或者至少我没有遇到过这种方法)。它只是杀死进程。

          例如,如果您在断点处停止然后按停止,则代码不会继续执行到终止 - 它只是退出。

          如果应用程序由于某些外部因素(例如电源关闭)而停止,情况也是如此。在这种情况下,无论程序是否在 finally 块中,程序都无法执行任何代码!

          但是,我刚刚遇到了这个问题Visual Studio : executing clean up code when debugging stops,它的答案是:

          您可以使用 DTE (VisualStudio 自动化模型)编写宏 停止调试时将调用 发生了,下面是一个sn-p 想法。

          Private Sub DebuggerEvents_OnEnterDesignMode(ByVal Reason As EnvDTE.dbgEventReason, ByRef ExecutionAction As EnvDTE.dbgExecutionAction) Handles DebuggerEvents.OnEnterDesignMode
          
              If (Reason = dbgEventReason.dbgEventReasonStopDebugging) Then
                  // DO YOUR CLEAN UP CODE HERE
              End If
          End Sub
          

          因此,虽然您无法在应用程序中捕获执行的停止,但您可以在 Visual Studio 中对其进行处理。

          注意:Shay Erlichmen 不是我提供的答案!

          【讨论】:

          • 这仅适用于您有控制台应用程序。对于 Windows 应用程序,必须考虑其他事项 - 请参阅 msdn.microsoft.com/en-us/library/…msdn.microsoft.com/en-us/library/…
          • 宏很接近,但不太正确。它需要是 OnEnterDesignMode 事件,而不是 OnEnterBreakMode。 (OnEnterBreakMode 用于断点;OnEnterDesignMode 显然用于进程终止。)
          • @Joe - 干杯,正如我在回答中所说,我“借用”了其他人的回答(希望正确归因)。我会更新的。
          • 记住,finally 子句不会一直运行。阅读愉快:thedailywtf.com/articles/My-Tales
          • @Marcel - 是的。我想我应该限定这个 7 1/2 岁的答案:)
          【解决方案5】:

          您可以在程序启动时订阅Application.ThreadException 事件,然后再调用Application.Run。如果您的应用程序抛出异常,这将使您有机会做某事。但是,当您点击停止时,它不会为捕获调试器做任何事情。

          <SecurityPermission(SecurityAction.Demand, Flags:=SecurityPermissionFlag.ControlAppDomain)> _
          Public Shared Sub Main()
            AddHandler Application.ThreadException, AddressOf ErrorHandlerForm.Form1_UIThreadException
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)
          
             ' Run the application.
            Application.Run(New Form1())
          End Sub
          
          
          Private Shared Sub Form1_UIThreadException(ByVal sender As Object, ByVal t As ThreadExceptionEventArgs)
            ' Handle exception
          End Sub
          

          您的另一种选择是将 Application.Run 包含在 Try...Catch 块中,这应该会给您类似的结果。

          【讨论】:

            【解决方案6】:

            如果您的目标是 Windows Vista(或更高版本),您可能会对 RegisterApplicationRecoveryCallback API 感兴趣...

            http://msdn.microsoft.com/en-us/library/aa373345.aspx

            它没有解决调试场景,但它允许你在你的应用程序即将崩溃时做一些事情。

            您可以从 C# 调用/调用此 API(我已经这样做了),但请记住,当您的回调被调用时,您的应用程序已经处于非常糟糕的状态,您可以对状态做出很少的假设你的记忆。如果您有任何要在此例程中使用的内存中数据,我会将其放在一个非常一般范围内的静态数据中,以便您在回调例程时尽可能避免“整理”它运行。

            还有一些其他有趣的 API,与此相关,可让您在失败后自动重启应用等。

            【讨论】:

              【解决方案7】:

              “实现目标的正常方法”是确保您的应用程序永远不会崩溃。

              您还可以提供一个独立的应用程序,让系统管理员可以释放任何可能因任何原因(断电,...)而留下的文件锁。此类应用程序也可用于解决此问题。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-02-18
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-02-25
                相关资源
                最近更新 更多