Instance method call Dispose

Is correct that a public method calls the Dispose of IDisposable in the same class?

Eg

public class Worker : IDisposable
{
    public void Close()
    {
       SendCloseCommand();
       Dispose();
    }

    public void Dispose()
    {
       ////other resources release
    }

    private void SendCloseCommand()
    {
    }
}

Another thing about disposable pattern: If the Close should be always called, is better that is called from the Dispose method or not?

If not, I should put the usage of the Worker class in a try/catch/finally everywhere, to call the Close. Right?

The correct design should instead be?

public class Worker : IDisposable
{
    public void Close()
    {
       SendCloseCommand();
    }

    public void Dispose()
    {
       Close();
       ////other resources release
    }

    private void SendCloseCommand()
    {
        ////other stuff
    }
}

If you look at Microsoft implementation for StreamReader , Dispose gets called from Close ,

public override void Close()
{
    Dispose(true);
}

and also the implementation for Dispose closes the stream as well by calling Close of base Stream .

protected override void Dispose(bool disposing)
{
    // Dispose of our resources if this StreamReader is closable.
    // Note that Console.In should be left open.
    try {
        // Note that Stream.Close() can potentially throw here. So we need to 
        // ensure cleaning up internal resources, inside the finally block.  
        if (!LeaveOpen && disposing && (stream != null))
            stream.Close();
    }
    finally {
        if (!LeaveOpen && (stream != null)) {
            stream = null;
            encoding = null;
            decoder = null;
            byteBuffer = null;
            charBuffer = null;
            charPos = 0;
            charLen = 0;
            base.Dispose(disposing);
        }
    }
}

In your class implementation, I would call the Dispose from your Close method as you are doing in your first code snippet. In Dispose , I would check for Worker status, if it is not closed then close it using SendCloseCommand , and then release resources.

public void Dispose()
{
   if(this.Status != Closed) // check if it is not already closed
     {
         SendCloseCommand();
     }

   ////other resources release
}

This will ensure your resources disposal, even if your class is used with using statement, or if any one calls Close manually.

Just remember to check status of your Worker object, before issuing Close Command.


Microsoft has some suggestions about having a Close method on a class implementing IDisposable . It is part of the Dispose Pattern guidelines:

CONSIDER providing method Close() , in addition to the Dispose() , if close is standard terminology in the area.

When doing so, it is important that you make the Close implementation identical to Dispose and consider implementing the IDisposable.Dispose method explicitly.

public class Stream : IDisposable {
    IDisposable.Dispose(){
        Close();
    }
    public void Close(){
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

So Microsofts suggestion is to hide Dispose and let it call Close to do the actual cleanup. Also, remember the guideline about multiple calls to Dispose :

DO allow the Dispose(bool) method to be called more than once. The method might choose to do nothing after the first call.

Following these guidelines makes your code consistent with the .NET library and you will avoid any confusion about if your class should be closed or disposed for proper cleanup.

链接地址: http://www.djcxy.com/p/54520.html

上一篇: 任何意义在Dispose()中设置obj = null(Nothing)?

下一篇: 实例方法调用Dispose