C#对应用程序崩溃执行最后一个操作

时间:2009-06-23 10:41:01

标签: c# exception

我不确定我想要的是否有合适的术语,因为我在谷歌尝试过的任何东西都没有购买任何东西。

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

我还想在使用停止按钮停止调试时捕获这一点,因为据我所知,使用停止按钮与通过应用程序中的正常过程退出应用程序非常不同。

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

干杯

7 个答案:

答案 0 :(得分:4)

在一个进程被杀之后你无法做任何事情。

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

您必须担心第二个进程崩溃或被杀,等等。在所有可能的情况下都不容易使它工作,但总比没有好。

答案 1 :(得分:1)

你的第一个要求的答案是(最基本的):

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

然而,在处理Windows应用程序时还有其他注意事项,正如RichardOD在此处的评论中指出的那样 - http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspxhttp://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx

你的第二个要求的答案是否是你无法捕获在调试器中停止的应用程序(或者至少我没遇到过这种方式)。它只会杀死这个过程。

例如,如果你已经在一个断点处停了下来然后按下停止,那么代码就不会继续执行到终止 - 它只是退出。

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

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

  

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

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提供的答案不是我!

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

您可以在程序启动时订阅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

你的另一个选择就是在Try ... Catch块中包围你的Application.Run,​​它可以给你类似的结果。

答案 5 :(得分:0)

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

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

它没有解决调试方案,但它确实允许您在应用程序即将崩溃时执行某些操作。

你可以从C#调用这个API(我已经完成了),但请记住,当你的回调被调用时你的应用程序已经处于非常糟糕的状态,你可以对状态作出很少的假设你的记忆如果你想在这个例程中使用任何内存中的数据,我会把它放在一个非常通用的静态范围内,以便你有最好的机会在你的回调例程中没有“整理”它运行。

还有一些与此相关的有趣的API,允许您在失败后自动重启应用程序等。

答案 6 :(得分:0)

“实现您正在尝试的正常方式”是确保您的应用程序永远不会崩溃。

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