的Finalize()时例外:您使用什么样的方法来检测垃圾收集器时异常?方法来、异常、垃圾、收集器

2023-09-03 01:45:59 作者:谁的年少不轻狂@

我开发一个pretty的广泛的系统,.NET,其中涉及大量的系统编程。大多数时候,我使用了IDisposable模式来处理资源的处置,但有时这并不适用(或遗漏错误),并最终确定在资源被销毁()。这可能发生在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?

另外:?是否有可能引发某种全球性的终结扔事件,至少记录,这非常的问题发生

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

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

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.

终结应该永远只能处置的非托管的资源 - 通常的模式是调用一个方法,保护无效的Dispose(BOOL处置)设置为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.