Using IDisposable interface to build unmanaged resource objects

Keywords: C# Database socket

Managed and unmanaged resources

In. Net, there are two kinds of resources used by objects: managed resources and unmanaged resources. Managed resources are managed by CLR and do not need to be controlled manually by developers. Managed resources in. Net mainly refer to "memory of objects in the heap"; unmanaged resources refer to some internal resources (such as operating system resources) outside managed memory used by objects. CLR does not manage these resources and need to be controlled by developers. The unmanaged resources used by. Net objects mainly include I/O flow, database connection, Socket connection, window handle and other resources directly related to the operation of the operating system.

Manage unmanaged resources

When an object is no longer in use, we should release the unmanaged resources it uses and return them to the operating system, or wait until the CLR reclaims its memory in the queue. This part of memory will become unreachable. It can only be returned to the system after the entire application runs. So we should release the unmanaged resource when the object instance is in the reachable state and the existing object reference points to it.

Using IDisposable interface to construct objects with unmanaged resource types

There is an interface for idisposted in the. net class library. Almost every type that uses unmanaged resources should implement this interface. So if we see the type that implements this interface, we should also think of unmanaged resources in this type for the first time. Idispost interface is a principle for managing unmanaged resources of objects. The code is as follows:

interface IDisposable
{
    void Dispose();
}
class ABase:IDisposable
{
    bool _disposed = false;
    public bool Disposed
    {
        get
        {
            return _disposed;
        }
    }
    public ABase(){}

    public void Dispose()
    {
        if(_disposed)
        {
            Dispose(true);
            GC.SuppressFinalize(this);
            _disposed = true;
        }
    }

    protected virtual void Dispose(bool disposing)
    {
        if(disposing)
        {
            //release member's unmanaged resource
        }
        // release ABase's unmanaged resource
    }
    ~ABase
    {
        Dispose(false);
    }
}
class A : ABase
{
    public A()
    {

    }
    protected override void Dispose(bool disposing)
    {
        if(disposing)
        {
            // release member's unmanaged resource
        }
        // release A's unmanaged resource

        // release base class's unmanaged resource
        base.Dispose(disposing);
    }

}
class B:A
{
    public B()
    {

    }


    public void Dosomething()
    {
        if(Disposed)// if released, throw exception
        {
            throw new ObjectDisposedException(...);
        }
        // do something here
    }

    protected override void Dispose(bool disposing)
    {
        if(disposing)
        {
            // release member's unmanaged resource
        }
        // release B's Unmanaged resource
        base.Dispose(disposing);
    }
}

Posted by knowram on Mon, 09 Dec 2019 09:50:30 -0800