我搜索并没有找到确切的答案。我正在学习Implementing Dispose的正确方法。我想知道为什么需要2个bool。
答案 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
,因此通过将其设置为leaveOpen
,true
将不会StreamWriter
基础流