130

.NET 中托管资源和非托管资源这两个术语是什么意思?他们是如何进入画面的?

4

5 回答 5

95

术语“非托管资源”通常用于描述不受垃圾收集器直接控制的东西。例如,如果您打开与数据库服务器的连接,这将使用服务器上的资源(用于维护连接)以及客户端计算机上可能的其他非 .net 资源,前提是提供程序不是完全用托管代码编写的。

这就是为什么对于像数据库连接这样的东西,建议您这样编写代码:

using (var connection = new SqlConnection("connection_string_here"))
{
    // Code to use connection here
}

这样可以确保.Dispose()在连接对象上调用它,从而确保清除所有非托管资源。

于 2010-08-31T08:18:35.170 回答
39

托管资源是纯 .NET 代码并由运行时管理并受其直接控制的资源。

非托管资源是非托管资源。文件句柄、固定内存、COM 对象、数据库连接等。

于 2010-08-31T08:18:04.157 回答
23

在问答中什么是非托管资源?1布鲁斯·伍德发布了以下内容:

我这样想术语“托管”和“非托管”:

“托管”是指 .NET 沙箱中的任何内容。这包括所有 .NET Framework 类。

“非托管”是指 .NET 沙箱之外的荒野。这包括通过调用 Win32 API 函数返回给您的任何内容。

如果您从不调用 Win32 API 函数并且从不取回任何 Win32“句柄”对象,那么您就没有持有任何非托管资源。通过 .NET Framework 类方法打开的文件和流都是托管包装器。

评论:您可能没有直接持有非托管资源。但是,您可能通过诸如System.IO.FileStream之类的托管“包装类”间接持有非托管资源。这样的包装类通常实现IDisposable(直接或通过继承)。

...许多托管(.NET Framework)对象在其中包含非托管资源,您可能希望尽快 Dispose() 处理它们,或者至少为调用者提供这样做的机会。这就是编写自己的 Dispose() 方法的地方。本质上,实现 IDisposable() 为您做了两件事:

  1. 允许您摆脱直接从 .NET 背后的操作系统获取的任何资源(非托管资源)。

  2. 允许您和您的调用者释放大量的 .NET 对象/.NET 对象,这些对象在您/您的调用者想要立即释放的肮脏的小手中持有宝贵的资源。

注释:通过实现IDisposable并因此提供一种Dispose()方法,您使您的类的用户能够以确定性的方式释放您的类的实例持有的任何非托管资源。


1链接最初在Sachin Shanbhag 的回答中共享。引用的材料日期为 2005-11-17。请注意,我对引用的内容进行了轻微的复制编辑。

于 2015-11-23T21:27:41.277 回答
8

托管资源和非托管资源之间的基本区别在于垃圾收集器知道所有托管资源,在某个时间点,GC 会出现并清理与托管对象关联的所有内存和资源。GC 不知道非托管资源,例如文件、流和句柄,因此如果您没有在代码中明确清理它们,那么您最终会导致内存泄漏和资源锁定。

有关更多详细信息 - http://bytes.com/topic/c-sharp/answers/276059-what-unmanaged-resources

于 2010-08-31T08:19:13.190 回答
0

托管资源是可以由垃圾收集器释放的资源,而非托管资源不能由垃圾收集器释放,为此需要析构函数。

于 2012-07-02T11:14:02.463 回答