Answers:
术语“非托管资源”通常用于描述不直接在垃圾收集器控制下的内容。例如,如果打开与数据库服务器的连接,这将使用服务器上的资源(用于维护连接),并且可能会使用客户端计算机上的其他非.net资源(如果提供程序不是完全用托管代码编写的)。
这就是为什么对于诸如数据库连接之类的东西,建议您这样编写代码:
using (var connection = new SqlConnection("connection_string_here"))
{
// Code to use connection here
}
这样可以确保.Dispose()
在连接对象上调用该方法,从而确保清除所有非托管资源。
在“问答”中,什么是非托管资源?1,布鲁斯伍德发表了以下内容:
我以这种方式考虑术语“托管”和“非托管”:
“托管”是指.NET沙箱中的所有内容。这包括所有.NET Framework类。
“不受管理”是指.NET沙箱外部的荒野。这包括通过调用Win32 API函数返回的所有内容。
如果您从不调用Win32 API函数并且从不获取任何Win32“句柄”对象,那么您就不会持有任何非托管资源。通过.NET Framework类方法打开的文件和流都是托管包装。
评论:您可能没有持有非托管资源直接。但是,您可能通过诸如System.IO.FileStream之类的托管“包装器类” 间接持有非托管资源。这种包装器类通常实现IDisposable(直接或通过继承)。
...许多托管(.NET Framework)对象都在其中保存着非托管资源,您可能希望尽快对其进行Dispose(),或至少为调用者提供这样做的机会。这就是编写自己的Dispose()方法的地方。本质上,实现IDisposable()为您做两件事:
允许您摆脱直接从.NET背后的操作系统获取的任何资源(非托管资源)。
允许您和您的呼叫者释放沉重的.NET对象/.NET对象,这些对象在您/呼叫者现在要释放的肮脏小手中持有着宝贵的资源。
注释:通过实现IDisposable
并由此提供一种Dispose()
方法,您使您的类的用户能够确定性地释放类的实例所拥有的任何非托管资源。
1 Link最初在Sachin Shanbhag的答案中共享。引用日期为2005-11-17的材料。请注意,我已经轻轻地复制了引用内容。
托管资源和非托管资源之间的基本区别在于,垃圾收集器知道所有托管资源,在某个时间点,GC会来清理所有与托管对象相关联的内存和资源。GC不了解非托管资源,例如文件,流和句柄,因此,如果不在代码中显式清除它们,则会导致内存泄漏和资源锁定。
有关更多详细信息-http://bytes.com/topic/c-sharp/answers/276059-what-unmanaged-resources