Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 非托管资源和Dispose()_C#_Dispose_Unmanagedresources - Fatal编程技术网

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分配内存;这将被视为非托管资源。)

例如,该类调用Windows API打开一个文件,
FileStream
在内部为其保留一个文件句柄。该文件句柄表示必须在某个点释放的非托管资源

FileStream
在后台使用Windows API函数。它是从表示非托管资源的
CreateFile
返回的句柄

如果不释放这些句柄,它们将在程序期间保持分配状态,但所有具有非托管资源的.Net类都提供了一个
终结器
(请参见下文),以确保它们通常会在某个时间被释放

(但是,如果您正在编写自己的文件处理类,却忘记在任何地方释放文件句柄,则文件将保持打开状态,直到程序退出。)

通常,此类非托管资源将在两个位置释放:

  • Dispose()方法。这应该是处理非托管资源的正常方式

  • 这个。这是万不得已的机制。如果一个类有一个终结器,垃圾收集器将在清理一个死对象时调用它。如果程序员忘记调用Dispose(),任何具有非托管资源的类都应该有一个终结器来清理

这有点简单,但我希望它能帮助你理解它


有关完整详细信息,请参阅。

有些人认为非托管资源与Windows API调用或其他类似内容相关,但这是一个实现细节。非托管资源的基本特征是,它代表了外部实体状态的一个方面,该状态是为了拥有资源的对象的利益而维护的,而对其他实体可能造成损害,如果对所有者的所有引用都被放弃,外部实体将继续维护它——毫无用处。注意,外部实体可以是任何东西,任何地方。Windows API句柄代表了可能性的一小部分(获取句柄的对象要求Windows使系统的某些方面可供其专用,而不利于任何其他希望使用它们的代码)。外部实体完全可能位于同一程序集中(特别是如果资源是锁或事件订阅),或者可能位于另一个大陆(如果资源是远程计算机上的文件)

对象通过通知代表其行事的实体不再需要这样做来释放资源。托管资源是一个.NET堆对象,它可能拥有托管或非托管资源的某些组合,但如果放弃它,其资源可能会被释放