最终,所有东西都是不可管理的资源。
不对。除了由CLR对象使用的内存(由框架管理(分配和释放))以外的所有内容。
实现IDisposable
和调用Dispose
不保留任何非托管资源的对象(直接或通过依赖对象间接)是没有意义的。它不能使确定的对象释放,因为您不能总是自己直接释放对象的CLR内存,因为它总是GC
这样做。对象是引用类型,因为在方法级别直接使用值类型时,堆栈操作会分配/释放值类型。
现在,每个人都声称自己的答案是正确的。让我证明我的。根据文件:
Object.Finalize方法允许对象尝试释放资源并执行其他清理操作,然后再由垃圾回收将其回收。
换句话说,对象的CLR内存在Object.Finalize()
调用后立即释放。[注意:如果需要,可以显式跳过此调用]
这是没有可管理资源的一次性课程:
internal class Class1 : IDisposable
{
public Class1()
{
Console.WriteLine("Construct");
}
public void Dispose()
{
Console.WriteLine("Dispose");
}
~Class1()
{
Console.WriteLine("Destruct");
}
}
请注意,析构函数隐式调用Finalize
继承链中的每个Object.Finalize()
这是Main
控制台应用程序的方法:
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Class1 obj = new Class1();
obj.Dispose();
}
Console.ReadKey();
}
如果致电Dispose
是释放托管电话的一种方式确定性对象的方法,那么每个“ Dispose”都会紧随其后的是“ Destruct”,对吗?自己看看会发生什么。从命令行窗口运行此应用程序是最有趣的。
注意:有一种方法可以强制GC
收集当前应用程序域中待定案的所有对象,但不能收集单个特定对象的对象。不过,您无需调用Dispose
即可在终结队列中包含一个对象。强烈建议不要强制收集,因为这可能会损害整体应用程序性能。
编辑
有一个例外-状态管理。Dispose
如果您的对象碰巧管理外部状态,则可以处理状态更改。即使状态不是非托管对象,由于有特殊的处理,使用它就像使用它一样非常方便IDisposable
。示例将是安全上下文或模拟上下文。
using (WindowsImpersonationContext context = SomeUserIdentity.Impersonate()))
{
}
这不是最佳示例,因为在WindowsImpersonationContext
内部使用系统句柄,但您会得到图像。
最重要的是,在实现时,IDisposable
您需要(或计划拥有)该Dispose
方法中有意义的事情。否则,那只是浪费时间。IDisposable
不会更改GC管理对象的方式。