C#实现配置 - 为什么需要检查配置和配置?

时间:2016-03-10 09:08:17

标签: c# .net memory-management idisposable

我搜索并没有找到确切的答案。我正在学习Implementing Dispose的正确方法。我想知道为什么需要2个bool。

  1. 为什么需要处理?只有析构函数调用Dispose(false),为什么析构函数不强制释放托管资源?
  2. 为什么需要处置?如果已经处理了这个对象,那么如何调用Dispose方法呢?你能说出调用Dispose并处理掉的情况吗?

2 个答案:

答案 0 :(得分:1)

disposing布尔值表示从哪里调用Dispose。它是通过YourObject.Dispose还是using语句显式调用的,还是从终结器线程中隐式调用的。

需要进行区分,因为从终结器线程运行Dispose时,无法保证任何托管对象在对象中仍然存在,因此将处理仅限制为该类型所拥有的非托管资源。

disposed布尔值用于标记对象已被处置。比方说,例如,一个人确实处置了对象,但实现缺少GC.SuppressFinalize(this)。即使对象已被释放,它仍然会在终结器执行后再次运行,并尝试再次释放那些已经释放的非托管资源。

您提供的文档中的示例很好地解释了这一点:

protected virtual void Dispose(bool disposing)
{
    if (!disposed)
    {
        if (disposing)
        {
            // Free other state (managed objects).
        }

        // Free your own state (unmanaged objects).
        // Set large fields to null.
        disposed = true;
    }
}

答案 1 :(得分:1)

对于第二个问题:Dispose()方法应该可以无问题地调用两次(参见IDisposable.Dispose()

  

如果多次调用对象的Dispose方法,则该对象必须忽略第一个之后的所有调用。如果多次调用Dispose方法,则该对象不得抛出异常。除Dispose之外的实例方法可抛出ObjectDisposedException资源已经处理好的时候。

常见的情况是将Stream对象传递给另一个带有“所有权”的Stream对象:

using (var ms = new MemoryStream())
{
    using (var sw = new StreamWriter(ms))
    //using (var sw = new StreamWriter(zip, Encoding.UTF8, 4096, true))
    {

    }

    // false: ms has already been disposed
    bool canWrite = ms.CanWrite;
}

StreamWriter通常取得对基础流的所有权(在本例中为ms),因此当调用Dispose()的{​​{1}}时,StreamWriter也是Dispose() {}}} {}}}但请注意,即使MemoryStream位于MemoryStream块中,也会再次调用using

此处没有问题,因为各种Dispose()类的Dispose()已正确实现。如果你想避免这个双Stream,几乎所有的Dispose()类都有一个重载,告诉他们是否必须对基础Stream取得所有权(参见注释行...参数被称为Stream,因此通过将其设置为leaveOpentrue将不会StreamWriter基础流