这是IDisposable的实现是否正确? [英] Is this IDisposable implementation correct?

查看:126
本文介绍了这是IDisposable的实现是否正确?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我永远记住所有为实现IDisposable接口的规则,所以我试图想出了负责这一切,使IDisposable的易于实现的基类。我只是想听听你的意见,如果这个实现是确定的,因为它是还是你看到的东西,我可以提高。这个基类的用户应该从中得到,然后实现两个抽象方法 ReleaseManagedResources() ReleaseUnmanagedResources()。因此,这里是code:

 公共抽象类一次性:IDisposable的
{
    私人布尔_isDisposed;
    私人只读对象_disposeLock =新的对象();

    ///<总结>
    ///调用这个类的用户提供免费的托管和非托管资源
    ///< /总结>
    公共无效的Dispose(){
        DisposeManagedAndUnmanagedResources();
    }

    ///<总结>
    ///终结被称为垃圾收集器来释放非托管资源
    ///< /总结>
    〜一次性(){//派生类的终结器会自动调用它的基本终结
        DisposeUnmanagedResources();
    }

    私人无效DisposeManagedAndUnmanagedResources(){
        锁定(_disposeLock)//使线程安全
            如果(!_isDisposed){//确保只有被调用一次
                尝试{//燮preSS异常
                    ReleaseManagedResources();
                    ReleaseUnmanagedResources();
                }
                最后 {
                    GC.Sup pressFinalize(本);从结束队列//删除,因为cleaup已经完成,所以,没有必要的垃圾收集器调用的Finalize()了
                    _isDisposed = TRUE;
                }
            }
    }

    私人无效DisposeUnmanagedResources(){
        锁定(_disposeLock)//使线程安全的,因为至少终结在不同的线程中运行
            如果(!_isDisposed){//确保只有被调用一次
                尝试{//燮preSS异常
                    ReleaseUnmanagedResources();
                }
                最后 {
                    _isDisposed = TRUE;
                }
            }
    }

    保护抽象无效ReleaseManagedResources();
    保护抽象无效ReleaseUnmanagedResources();

}
 

解决方案

您正在访问的终结被管理对象_disposeLock。它可能已经被垃圾收集即可。不知道这样的影响将因为你只用它来锁定。

主题安全似乎有点小题大做。我不认为你需要担心的GC线程和应用程序线程之间的冲突。

否则,它看起来是正确的。

I can never remember all the rules for implementing the IDisposable interface, so I tried to come up with a base class that takes care of all of this and makes IDisposable easy to implement. I just wanted to hear your opinion if this implementation is ok as it is or whether you see something I could improve. The user of this base class is supposed to derive from it and then implement the two abstract methods ReleaseManagedResources() and ReleaseUnmanagedResources(). So here is the code:

public abstract class Disposable : IDisposable
{
    private bool _isDisposed;
    private readonly object _disposeLock = new object();

    /// <summary>
    /// called by users of this class to free managed and unmanaged resources
    /// </summary>
    public void Dispose() {
        DisposeManagedAndUnmanagedResources();
    }

    /// <summary>
    /// finalizer is called by garbage collector to free unmanaged resources
    /// </summary>
    ~Disposable() { //finalizer of derived class will automatically call it's base finalizer
        DisposeUnmanagedResources();
    }

    private void DisposeManagedAndUnmanagedResources() {
        lock (_disposeLock) //make thread-safe
            if (!_isDisposed) { //make sure only called once
                try { //suppress exceptions
                    ReleaseManagedResources();
                    ReleaseUnmanagedResources();
                }
                finally {
                    GC.SuppressFinalize(this); //remove from finalization queue since cleaup already done, so it's not necessary the garbage collector to call Finalize() anymore
                    _isDisposed = true;
                }
            }
    }

    private void DisposeUnmanagedResources() {
        lock (_disposeLock) //make thread-safe since at least the finalizer runs in a different thread
            if (!_isDisposed) { //make sure only called once
                try { //suppress exceptions
                    ReleaseUnmanagedResources();
                }
                finally {
                    _isDisposed = true;
                }
            }
    }

    protected abstract void ReleaseManagedResources();
    protected abstract void ReleaseUnmanagedResources();

}

解决方案

You are accessing the managed object _disposeLock in the finalizer. It may have already been garbage-collected by then. Not sure what the implications of this would be as you are only using it to lock.

Thread-safety seems like overkill. I don't think you need to worry about contention between the GC thread and your application thread.

Otherwise it looks correct.

这篇关于这是IDisposable的实现是否正确?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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