C# 非托管资源和Dispose()
我读了一些关于C# 非托管资源和Dispose(),c#,dispose,unmanagedresources,C#,Dispose,Unmanagedresources,我读了一些关于Dispose()方法的文章,发现非托管资源应该从Dispose()方法(或finalize()方法)中显式释放,文章说文件句柄和数据库连接对象就是非托管资源的示例。有人能解释为什么这些是非托管的,以及如果在Dispose()中处理不当会发生什么情况吗?我不知道什么是文件句柄。它们存在于哪里 在这种情况下,也许最容易这样想: 非托管资源是通过执行Windows API调用获得的任何资源,该调用返回必须在某个点释放的 唯一的另一种资源是内存。如果它是由.Net分配的,则会自动进行管
Dispose()
方法的文章,发现非托管资源应该从Dispose()
方法(或finalize()方法)中显式释放,文章说文件句柄和数据库连接对象就是非托管资源的示例。有人能解释为什么这些是非托管的,以及如果在Dispose()中处理不当会发生什么情况吗?我不知道什么是文件句柄。它们存在于哪里 在这种情况下,也许最容易这样想:
- 非托管资源是通过执行Windows API调用获得的任何资源,该调用返回必须在某个点释放的
- 唯一的另一种资源是内存。如果它是由.Net分配的,则会自动进行管理。(请注意,可以使用Windows API分配内存;这将被视为非托管资源。)
FileStream
在内部为其保留一个文件句柄。该文件句柄表示必须在某个点释放的非托管资源
FileStream
在后台使用Windows API函数。它是从表示非托管资源的CreateFile
返回的句柄
如果不释放这些句柄,它们将在程序期间保持分配状态,但所有具有非托管资源的.Net类都提供了一个终结器
(请参见下文),以确保它们通常会在某个时间被释放
(但是,如果您正在编写自己的文件处理类,却忘记在任何地方释放文件句柄,则文件将保持打开状态,直到程序退出。)
通常,此类非托管资源将在两个位置释放:
- Dispose()方法。这应该是处理非托管资源的正常方式
- 这个。这是万不得已的机制。如果一个类有一个终结器,垃圾收集器将在清理一个死对象时调用它。如果程序员忘记调用Dispose(),任何具有非托管资源的类都应该有一个终结器来清理
有关完整详细信息,请参阅。有些人认为非托管资源与Windows API调用或其他类似内容相关,但这是一个实现细节。非托管资源的基本特征是,它代表了外部实体状态的一个方面,该状态是为了拥有资源的对象的利益而维护的,而对其他实体可能造成损害,如果对所有者的所有引用都被放弃,外部实体将继续维护它——毫无用处。注意,外部实体可以是任何东西,任何地方。Windows API句柄代表了可能性的一小部分(获取句柄的对象要求Windows使系统的某些方面可供其专用,而不利于任何其他希望使用它们的代码)。外部实体完全可能位于同一程序集中(特别是如果资源是锁或事件订阅),或者可能位于另一个大陆(如果资源是远程计算机上的文件) 对象通过通知代表其行事的实体不再需要这样做来释放资源。托管资源是一个.NET堆对象,它可能拥有托管或非托管资源的某些组合,但如果放弃它,其资源可能会被释放