如何判断资源是否不受管理?

时间:2018-01-31 17:05:36

标签: c# garbage-collection dispose using-statement unmanagedresources

我使用Visual Studio 2017编写C#应用程序。我努力通过利用"使用"来处理我实例化的所有对象。声明。如果我实例化一个不基于可隐式转换为System.IDisposable'的类型的对象,Visual Studio会发出警告。此示例导致VS显示警告(C#):

using (uri = new System.Uri(stringVarWithPath))
{
}

所有未实施Dispose方法的类型是否都不受管理?我问因为"实施一个Dispose方法" (https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose)似乎暗示它仅适用于非托管资源。

1 个答案:

答案 0 :(得分:6)

反过来说。

首先,管理您在.NET中使用的所有类型。但是一些托管类型封装了非托管资源,例如Windows句柄。

封装非托管资源的类型通常实现// Instantiate the EM and inject it into the DAOs EntityManager em = emf.createEntityManager(); // ... whatever comes here - most likely: doing some CRUD operations... IDisposable接口允许您通过调用IDisposable或将它们放入Dispose()来显式释放这些对象持有的非托管资源。在后一种情况下,退出using的范围时会自动调用Dispose()

无论如何,即使没有在实现它的对象上调用using,精心设计的类也应该在Dispose()(基本上是析构函数)中释放它们的非托管资源。但是GC会调用Finalize(),而我们不知道调用GC的频率,这会释放资源的非确定性过程。如果没有Finalize(),我们会长时间持有昂贵的非托管资源,远远超出必要的范围。

当某个类型没有实现IDisposable时,它表明它不包含任何非托管资源,并且没有理由明确处理(当然,如果类型设计得很好)

请注意,实现IDisposable的某些类型实际上并不包含任何非托管资源。例如,一个测量执行时间的类可以实现IDisposable,以便在构造函数中保存时间戳,然后在IDisposable中获取当前时间戳并计算已用时间并将其报告给某些日志记录机制。当您将这样的类放在Dispose中时,您可以方便地测量代码块的执行时间。