16

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

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

有没有办法做到这一点?

4

2 回答 2

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 设置的时间跨度内完成,它将升级为粗鲁的应用程序域卸载。

于 2012-07-13T23:02:43.260 回答
1

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

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

最好的办法是在块IDisposable内使用您的对象。 只有这样,您才能保证它们何时会被处理掉。using

于 2012-07-13T21:19:10.783 回答