Calling GC.SuppressFinalize() from within a finalizer

故事扮演 提交于 2020-01-13 04:42:29

问题


I was working on a class in which I had to dispose of managed and unmanged resources which looked something like this (only the disposing part, obviously):

class MyDisposingExample : IDisposable
{
    public void Dispose()
    {
        Dispose(true);
    }

    private void Dispose(bool callFromDispose)
    {
        // free unmanaged resources here
        if (callFromDispose)
        {
            // free managed resources here
            GC.SuppressFinalize(this);
        }
    }

    ~MyDisposingExample()
    {
        Dispose(false);
    }
}

And then a thought occurred to me. Why bother with the second Dispose function? Why can't I just do this:

class MyDisposingExample2 : IDisposable
{
    public void Dispose()
    {
        // free unmanaged resources here
        // free managed resources here
        GC.SuppressFinalize(this);
    }

    ~MyDisposingExample2()
    {
        Dispose();
    }
}

The usual disposing pattern addresses several problems, all of which seem to be solved by this example, without the additional method.

1) If the method Dispose() is explicitly called, it frees the managed resources, the unmanaged resources and suppresses the finalizer so that the resources won't be freed again later.

2) If the method Dispose() was not explictly called, the finalizer will run Dispose(), free managed resources, free unmanaged resources and suppress the finalizer (we'll get back to this point later).

On the face of it, this pattern provides everything the previous pattern does. I can dispose of my object explicitly if I don't require it anymore, my object is implicitly disposed if I forget to dispose of it myself and there is no fear of resources being freed twice.

The only fly in the ointment seems to be that I am calling GC.SuppressFinalize() from within the finalizer itself, but... why not? According to MSDN:

This method sets a bit in the object header of obj, which the runtime checks when calling finalizers.

So all I'm doing is setting a bit. This shouldn't affect the finalizer once it's running as the bit check must occur before the finalizer is called.

As I haven't seen this pattern anywhere, I must assume there is something wrong with it. What am I missing?

来源:https://stackoverflow.com/questions/36344293/calling-gc-suppressfinalize-from-within-a-finalizer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!