实例方法调用Dispose

时间:2014-08-19 13:08:38

标签: c# design-patterns dispose idisposable

公共方法在同一个类中调用IDisposable的Dispose是否正确?

E.g。

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

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

    private void SendCloseCommand()
    {
    }
}

关于一次性模式的另一件事: 如果应该总是调用Close,那么从Dispose方法调用是否更好?

如果没有,我应该在try / catch / finally的所有地方使用 Worker 类,以调用Close。正确?

正确的设计应该是?

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

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

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

2 个答案:

答案 0 :(得分:4)

如果您查看Microsoft implementation for StreamReader,则会Dispose调用Close

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

以及Dispose的实施也会通过调用基座Close的{​​{1}}来关闭流。

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); } } } 方法中调用Dispose,就像您在第一个代码段中所做的那样。在Close中,我会检查Dispose状态,如果它未关闭,则使用Worker关闭它,然后释放资源。

SendCloseCommand

这将确保您的资源处理,即使您的类与public void Dispose() { if(this.Status != Closed) // check if it is not already closed { SendCloseCommand(); } ////other resources release } 语句一起使用,或者任何人手动调用using

请记住在发出Close Command之前检查Close对象的状态。

答案 1 :(得分:2)

Microsoft对在实现Close的类上使用IDisposable方法提出了一些建议。它是Dispose Pattern指南的一部分:

  

CONSIDER 除了Close()之外,还提供方法Dispose(),如果close是该区域的标准术语。

     

执行此操作时,务必使Close实现与Dispose相同,并考虑明确实施IDisposable.Dispose方法。

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

所以微软的建议是隐藏Dispose并让它调用Close来进行实际清理。另外,请记住有关Dispose的多次调用的指南:

  

DO 允许多次调用Dispose(bool)方法。第一次调用后,该方法可能选择不执行任何操作。

遵循这些指导原则可以使您的代码与.NET库保持一致,并且您可以避免对是否应关闭或处理您的类以进行适当清理而产生任何混淆。