C# 非托管资源究竟是什么?

C# 非托管资源究竟是什么?,c#,unmanaged,C#,Unmanaged,我想了解非托管资源。 有谁能给我一个基本的想法吗?托管资源和非托管资源的基本区别在于 垃圾收集器在某个时间点了解所有托管资源 GC将出现并清理所有相关的内存和资源 使用托管对象。GC不知道非托管资源,例如 作为文件、流和句柄,所以如果您没有在 您的代码将导致内存泄漏和资源锁定 从PoST中窃取,可以自由阅读整个帖子。< P>非托管资源是运行在.NET运行时(CLR)之外的(AcA.N.NET代码)。例如,调用Win32 API中的DLL,或者调用C++编写的.dll。托管资源基本上是指垃圾回收器

我想了解非托管资源。
有谁能给我一个基本的想法吗?

托管资源和非托管资源的基本区别在于 垃圾收集器在某个时间点了解所有托管资源 GC将出现并清理所有相关的内存和资源 使用托管对象。GC不知道非托管资源,例如 作为文件、流和句柄,所以如果您没有在 您的代码将导致内存泄漏和资源锁定


从PoST中窃取,可以自由阅读整个帖子。

< P>非托管资源是运行在.NET运行时(CLR)之外的(AcA.N.NET代码)。例如,调用Win32 API中的DLL,或者调用C++编写的.dll。

托管资源基本上是指垃圾回收器管理的“托管内存”。当您不再有对托管对象(使用托管内存)的任何引用时,垃圾收集器将(最终)为您释放该内存

非托管资源就是垃圾收集器所不知道的一切。例如:

  • 打开文件
  • 开放网络连接
  • 非托管内存
  • 在XNA中:顶点缓冲区、索引缓冲区、纹理等
通常,您希望在丢失对管理这些资源的对象的所有引用之前释放这些非托管资源。通过对该对象调用
Dispose
,或者(在C#)使用
using
语句来完成此操作,该语句将为您处理调用
Dispose

如果您忽略了正确处置非托管资源的
,垃圾收集器最终将在垃圾收集包含该资源的对象时为您处理该资源(这是“终结”)。但是,由于垃圾收集器不知道非托管资源的情况,所以它无法判断需要释放它们的程度-因此,您的程序可能会执行得很差或完全耗尽资源

如果您自己实现了一个处理非托管资源的类,那么您需要正确地实现
Dispose
Finalize

非托管资源不是一件事,而是一种责任。如果一个对象拥有一个非托管资源,这意味着(1)该对象外部的某个实体已被操作,如果未清理,可能会导致问题,(2)该对象拥有执行此类清理所需的信息,并负责进行清理

尽管许多类型的非托管资源与各种类型的操作系统实体(文件、GDI句柄、分配的内存块等)有着密切的关联,但除了清理的责任外,没有一种实体是由所有这些实体共享的。通常,如果一个对象有责任执行清理,它将有一个Dispose方法,该方法指示它执行它负责的所有清理

在某些情况下,对象会考虑到可能在没有任何人先调用Dispose的情况下放弃它们。GC允许对象请求通知它们已被放弃(通过调用名为Finalize的例程),对象可以使用此通知自己执行清理


不幸的是,“托管资源”和“非托管资源”等术语被不同的人用来表示不同的东西;坦率地说,从对象的角度来看,认为没有任何清理责任、只有在调用Dispose时才会处理的清理责任,或者应该通过Dispose处理的清理责任更有用,但是也可以通过Finalize来处理。

在.NET托管堆中为其分配内存的任何资源都是托管资源。CLR完全了解这种内存,并将尽一切努力确保它不会成为孤立内存。其他任何事情都是不受管理的。例如,与COM进行互操作可能会在进程内存空间中创建对象,但CLR不会处理它。在这种情况下,跨托管边界进行调用的托管对象应负责其之外的任何事情。

有些用户将打开的文件、数据库连接、分配的内存、位图、文件流等列为托管资源,而另一些用户则列为非托管资源那么它们是托管的还是非托管的?

我的意见是,响应更复杂:当您在.NET中打开文件时,可能会使用一些内置的.NET类System.IO.file、FileStream或其他东西。因为它是一个普通的.NET类,所以它是被管理的。但它是一个包装器,它在内部执行“脏工作”(使用Win32 DLL与操作系统通信,调用低级函数甚至汇编指令),真正打开文件。这是.NET所不知道的,非托管的。 但是,您可能可以使用汇编程序指令和绕过.NET文件函数自己打开该文件。那么句柄和打开的文件就是非托管资源

DB也是一样:如果使用一些DB程序集,那么就有DbConnection等类,它们是.NET所知道的,并且是托管的。但它们包装了非托管的“脏工作”(在服务器上分配内存,与服务器建立连接,…)。 如果您不使用这个包装类,自己打开一些网络套接字,并使用一些命令与自己的奇怪数据库通信,那么它是非托管的

这些包装器类(File、DbConnection等)是托管的,但它们内部使用非托管资源的方式与您相同,前提是您不使用包装器,而是自己做“脏活”。因此,这些包装器确实实现了Dispose/Finalize模式。他们的职责是允许程序员在不再需要包装器时释放非托管资源,并在包装器被垃圾收集时释放它们。包装纸w