实例方法调用Dispose

3

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

例如:

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

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

    private void SendCloseCommand()
    {
    }
}

关于一次性模式的另一件事情: 如果Close方法应该总是被调用,那么最好是从Dispose方法中调用它吗?
如果不是这样,我应该在每个地方都使用try/catch/finally来调用Close以使用Worker类。对吧?
正确的设计应该是什么?
public class Worker : IDisposable
{
    public void Close()
    {
       SendCloseCommand();
    }

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

    private void SendCloseCommand()
    {
        ////other stuff
    }
}
2个回答

4
如果您查看Microsoft实现的StreamReader,则Dispose将从Close中调用。
public override void Close()
{
    Dispose(true);
}

并且Dispose的实现也通过调用基类StreamClose方法关闭了流。

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);
        }
    }
}

在你的类实现中,我会像你在第一个代码片段中所做的那样,在你的Close方法中调用Dispose。在Dispose中,我会检查Worker的状态,如果它没有关闭,则使用SendCloseCommand将其关闭,然后释放资源。

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

   ////other resources release
}

这将确保您的资源被处理,即使您的类与using语句一起使用,或者任何人手动调用Close。只需记住在发出关闭命令之前检查Worker对象的状态。

2
事实上,我同意你的例子,我不想用try/catch/finally来填充代码,而是简单地使用using语句。 - Achille

2
Microsoft在实现IDisposable接口的类中提出了一些关于拥有Close方法的建议。这是Dispose Pattern指南的一部分:

如果在该领域中,关闭是标准术语,请考虑提供Close()方法,除了Dispose()

这样做时,重要的是使Close的实现与Dispose相同,并考虑显式实现IDisposable.Dispose方法。

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

Microsoft的建议是隐藏Dispose方法并让它调用Close方法来进行实际的清理。此外,请记住有关多次调用Dispose的准则:

允许多次调用Dispose(bool)方法。该方法在第一次调用后可能选择什么也不做。

按照这些指南编写代码可以使其与.NET库保持一致,并避免任何关于是否应关闭或处理您的类以进行适当的清理的混淆。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接