在应用程序崩溃时执行代码
Posted
技术标签:
【中文标题】在应用程序崩溃时执行代码【英文标题】:Executing code on application crash 【发布时间】:2011-01-29 16:15:48 【问题描述】:即使我的 C# 应用程序崩溃(删除临时文件等),我也想在执行结束时执行一些清理代码。在 C# 中可以做到这一点吗?
谢谢!
【问题讨论】:
非软件工程师所说的这个词是什么意思:任何导致应用程序崩溃的事件(任何线程中的未处理异常、除以 0、访问冲突、来自我的工作 DLL 的 C++ SEH等等)。 【参考方案1】:这取决于您所说的“崩溃”。
如果您想处理任何可能导致应用程序崩溃的未处理异常,您可以将事件处理程序附加到 AppDomain.UnhandledException 事件,然后在事件处理程序中处理任何错误。
此外,在 .Net 4.0 中有一个 AppDomain.FirstChanceException 在发生异常时在执行任何 catch 块之前调用。
但是,可能会发生真正的崩溃(例如从终结器引发的异常),导致无法轻松处理的致命应用程序退出,但在大多数情况下,AppDomain.UnhandledException 事件可能就足够了。
【讨论】:
我想在任何崩溃之前调用一个方法。 AppDomain.FirstChanceException 帮助了我。谢谢!【参考方案2】:如果您的应用程序崩溃,那么尝试执行清理代码是不安全的,您不知道什么已损坏,直到您的应用程序真正退出,文件可能被锁定等。
所以我建议你把这个清理代码放在应用程序启动上。让您的应用程序在启动时查找临时文件等,然后再创建正常的临时文件,如果找到它们,则可以删除它们或尝试修复/重用它们。
为了方便这一点,您可以让您的应用程序写入它创建的临时文件的日志,并在它关闭时删除该日志文件成功。这样,当您在启动时找到日志文件时,您就知道上次运行是崩溃,您必须进行清理。
当然,如果您允许应用程序的多个实例同时运行,这会变得更加复杂,但在崩溃时清理内容也是如此。
【讨论】:
【参考方案3】:您可以订阅多个事件以获得异常通知。
AppDomain.UnhandledException - 由应用域中未处理的异常触发。 Dispatcher.UnhandledException - 由 WPF Dispather 线程上未处理的异常触发。 Application.ThreadException - 由后台线程上未处理的异常触发。此外,正如其他人所提到的,围绕单个入口点的 finally 块将针对主线程上的任何异常而被命中。
[我不建议尝试从这些处理程序中恢复您的应用程序。特别是在 AppDomain.UnhandledException 事件的情况下,您的应用程序已经退出,您应该让它关闭。仅将这些处理程序用于最后一分钟的清理或记录。]
【讨论】:
【参考方案4】:如果清理您的应用程序至关重要,您可以创建一个监控应用程序,该应用程序将是用户实际启动的内容。它将启动您的主应用程序,然后监视其进程句柄。如果您的主应用程序崩溃,它的进程句柄将发出信号,并且您的监控应用程序可以清理甚至重新启动主应用程序,如果您愿意。我通常将它与一个命名的互斥锁结合使用,该互斥锁用于向监控应用发出信号,表明主应用希望关闭,这样它就不会重新启动它。
【讨论】:
【参考方案5】:这取决于您所说的“崩溃”是什么意思。如果您的意思是未处理的异常,您可以为 Application.ThreadException 创建一个处理程序。如果崩溃是在托管代码之外引起的,那么您无能为力。
【讨论】:
我希望的是我可以编写某种可覆盖的“终止”函数,它会因未处理的异常、访问冲突或任何其他可能导致我的应用程序崩溃的情况而被调用。大部分工作是由 C++ DLL 完成的,因此从它处理异常也很好。【参考方案6】:这就是try finally
的用途。将您的所有代码包装在您的 main
方法中,应该这样做。
【讨论】:
这在简单的场景下可能已经足够了,但是多线程应用呢?以上是关于在应用程序崩溃时执行代码的主要内容,如果未能解决你的问题,请参考以下文章