VisualStudio调试器退出时执行代码

时间:2012-07-13 21:15:06

标签: c# .net .net-4.0 dispose finalizer

我假设在终止调试时(例如通过点击“停止”按钮,或按Shift + F5),任何实现终结器或IDisposable的类都会被处理掉。

我有一些实现IDisposable的类。当应用程序从调试器退出时(或从生产中崩溃),我想做(尝试)并执行一些操作。现在,Dispose()似乎没有被调用,也没有终结器~MyClass(){}

有办法做到这一点吗?

2 个答案:

答案 0 :(得分:2)

对于正常停止Windows服务,您应该将代码放在Stop方法中。

http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.stop.aspx

一般情况下,粗鲁的线程中止和粗鲁的应用程序域卸载不会运行“正常”终结器 - 您可以在此MSDN文章中获得更多详细信息。

https://web-beta.archive.org/web/20150423173148/https://msdn.microsoft.com/en-us/magazine/cc163716.aspx

  

到目前为止,我只是谈到了线程中止,因为运行时在线程上抛出了ThreadAbortException。通常,这将导致线程终止。但是,线程可以处理线程中止,从而阻止它终止线程。为了解释这一点,运行时提供了一个更强大的动作,恰当地命名为粗鲁的线程中止。粗鲁的线程中止导致线程停止执行。发生这种情况时,CLR不保证线程上的任何退出代码都会运行(除非代码在CER中执行)。粗鲁,确实。

     

类似地,虽然典型的应用程序域卸载将优雅地中止域中的所有线程,但是粗鲁的应用程序域卸载将粗暴地中止域中的所有线程,并且不保证与该域中的对象相关联的正常终结器将运行。 SQL Server 2005是一个CLR主机,它使用粗鲁的线程中止和粗鲁的应用程序域卸载作为其升级策略的一部分。发生异步异常时,资源分配失败将升级为线程中止。当线程中止发生时,如果它没有在SQL Server设置的时间范围内完成,它将被升级为粗鲁的线程中止。同样,如果应用程序域卸载操作未在SQL Server设置的时间范围内完成,则它将升级为粗略的应用程序域卸载。 (请注意,刚刚提出的策略并不完全是SQL Server使用的策略,因为SQL Server还会考虑代码是否在关键区域中执行,但很快就会在该主题上执行)。

答案 1 :(得分:1)

好吧,CLR没有就你的对象何时被收集或处置做出任何承诺。

您可以尝试显式调用垃圾收集器,但我不认为这是推荐的方法。

最好的办法是使用IDisposable块内的using个对象 这是唯一一个在你被处置时得到保证的时候。