Finalize() 期间的异常:您使用什么方法来检测垃圾收集器时异常? [英] Exceptions during Finalize(): what methodology are you using to detect garbage collector-time exceptions?

查看:16
本文介绍了Finalize() 期间的异常:您使用什么方法来检测垃圾收集器时异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 .NET 开发一个相当广泛的系统,其中涉及大量系统编程.大多数时候,我使用 IDisposable 模式来处理资源处理,但有时这不适用(或被错误地遗漏)并且资源在 Finalize() 期间被破坏.这可能发生在 COM 互操作中,或者当析构函数调用 Dispose() 并且其中存在异常时.

I am developing a pretty extensive system in .NET, which involves a lot of system programming. Most time, I'm using the IDisposable pattern to handle resource disposal, but sometimes this isn't applicable (or left out by mistake) and resource gets destroyed during Finalize(). This might happen in COM interop, or when destructor calls Dispose() and there is an exception inside of it.

基本上:当终结器可能抛出时,并不总是能够清楚地看到和处理每个场景.当它发生时,应用程序肯定会崩溃.

Basically: it is not always possible to clearly see and handle each scenario when finalizer might throw. And when it happens, the application will most certainly crash.

我特别关注这类问题的原因是终结器不是由创建或使用对象的线程调用的,因此将异常与对象所在的上下文联系起来几乎是不可能的任务创建的.你得到的只是一些通用的 GC 线程.

The reason why I'm concerned with specifically this class of problems is that finalizers are not called by a thread that created or used an object, so it is almost impossible task to tie the exception to the context in which the object was created. All you are getting is some generic GC thread.

那么,现在向公众提问:如果您考虑到这些问题,您会采取什么措施来控制它们?标记对象?使用允许跟踪这些问题的第三方工具?

So, question to the public now: if you account for those kind of issues, what do you do to control them? Tag the objects? Use a 3rd party tool which allows tracking those issues?

另外:是否有可能触发某种全局Finalizer throw"事件,以至少记录这个问题已经发生?

Also: is it possible to trigger some sort of global "Finalizer threw" event, to at least log that this very problem has happened?

EDIT1:非常感谢所有提交宝贵意见的人,我想我现在对需要做的事情有点清楚了.我真正想从这个讨论中得到的最后一件事是,如果有人知道在终结器中触发异常代码的方法(即使应用程序崩溃仍然是不可避免的),那么我至少可以记录它,而不必修改每个的析构函数类.

EDIT1: Many thanks to everyone who submitted valuable input, I think I'm somewhat clearer now on what needs to be done. Last thing I would really like to get from this discussion is if somebody knows the methodology to trigger code on exception in finalizer (even if app crash is still inevitable), so that I could at least log it, without having to modify destructor of every class.

推荐答案

只有在 .NET 中直接拥有非托管资源(即不仅通过 IDisposable 成员)的类才需要终结器.此类类必须使用 MSDN 中描述的标准模式实现 IDisposable.

Finalizers are only needed in .NET for classes that directly own unmanaged resources (i.e. not only via an IDisposable member). Such classes must implement IDisposable using the standard pattern as described in MSDN.

终结器只应释放 非托管 资源 - 通常的模式是调用方法protected void Dispose(bool disposing)"并将 disposing 参数设置为 false.

The finalizer should only ever dispose unmanaged resources - the usual pattern is to call a method "protected void Dispose(bool disposing)" with the disposing argument set to false.

这个方法通常是这样实现的:

This method is typically implemented something like:

protected void Dispose(bool disposing)
{
    if (disposing)
    {
        // Dispose managed resources here.
        // (e.g. members that implement IDisposable)
        // This could throw an exception, but will *not* be called from the finalizer
        ...

    }
    ... Dispose unmanaged resources here.
    ... no need for any exception handling.
    ... Unlikely to get an exception, and if you do it will be fatal.
}

由于您只处理非托管资源,因此通常不应引用任何托管对象,也不需要包含任何异常处理.

Since you are only ever disposing unmanaged resources, you generally should not be referencing any managed objects and shouldn't need to include any exception handling.

这篇关于Finalize() 期间的异常:您使用什么方法来检测垃圾收集器时异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆