C#实施处置-为什么需要检查处置和处置?
我搜索了一下,没有找到确切的答案。我正在学习正确的学习方法。我想知道为什么需要这两个布尔C#实施处置-为什么需要检查处置和处置?,c#,.net,memory-management,idisposable,C#,.net,Memory Management,Idisposable,我搜索了一下,没有找到确切的答案。我正在学习正确的学习方法。我想知道为什么需要这两个布尔 为什么需要处理?只有析构函数调用Dispose(false),那么为什么析构函数不强制释放托管资源呢 为什么需要处置?如果此对象已被释放,如何调用Dispose方法?您能告诉我们一个场景,何时调用Dispose并且disposed为true吗 Dispose布尔值用于指示调用Dispose的位置。它是通过YourObject.Dispose或使用语句的显式调用的,还是从终结器线程隐式调用的 之所以需要这种区
Dispose
布尔值用于指示调用Dispose
的位置。它是通过YourObject.Dispose
或使用语句的显式调用的,还是从终结器线程隐式调用的
之所以需要这种区别,是因为当从终结器线程运行Dispose
时,无法保证对象中的任何托管对象仍然处于活动状态,因此仅将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;
}
}
对于第二个问题:Dispose()
方法应该可以调用两次而不会出现问题(请参阅:
如果多次调用对象的Dispose方法,则该对象必须忽略第一次调用之后的所有调用。如果多次调用其Dispose方法,则该对象不得引发异常。Dispose以外的实例方法可以在已释放资源时引发ObjectDisposedException
一种常见情况是将流
对象传递给另一个拥有“所有权”的流
对象:
StreamWriter
通常拥有底层流的所有权(在本例中为ms
),因此当调用StreamWriter
的Dispose()
时,Dispose()也被调用内存流的
…但请注意,即使是内存流
也位于using
块中,因此其Dispose()
将再次调用
这里没有问题,因为各种流
类的Dispose()
都得到了正确实现。如果要避免这种双重Dispose()
,几乎所有流
类都有一个重载,告诉它们是否必须拥有底层流
(参见注释行…参数名为leaveOpen
,因此通过将其设置为true
,StreamWriter
将不会Dispose()
底层流)您签出了吗?@Shazi谢谢,我会详细阅读它。如果disposing参数为false,则对象不会被处置。它是终结器(又名析构函数)这很重要,这意味着您无法处置存储在字段中的任何对象,它们可能已经被终结。为了安全起见,您需要处置,客户端代码可能会多次调用dispose。编写自己的终结器并实现一次性模式有一个非常可取的特点,99.9%的时间是错误的。Framework班级需要这样做,而不是你。怎么样,似乎你还没有提到。
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;
}