c# - Component类库中实现的Dispose方法在哪里

标签 c# .net c#-4.0 interface garbage-collection

好吧,我正在尝试了解可以通过代码显式完成的内存释放过程。

我在下面的 MS 线程中看到 Dispose 方法是在 Component 类中实现的。这里我有三个疑惑。

  1. Component 类派生自 IDisposable,但是,在这个类库中,我发现它没有实现 Dispose 方法,甚至看起来也不是“public void Dispose() { }”。但是当我只写一个类并声明一个没有任何主体的方法时,它给我编译时错误说,我应该定义主体或使它抽象。为什么会有这种差异?

  2. 我一般都是这样用的,比如说“connection.Dispose();”在 finally block 中处理 sqlconnection。据我了解,SqlConnection 派生自 DBConnection,后者又派生自 Component。当我查看 Component 类时,我只看到方法“public void Dispose();”的声明。那么具体实现在哪里呢?

  3. 我还看到了一些专门实现的代码,例如下面 MS 网站中给出的代码。他们为 Dispose 状态声明了一个 bool 变量,并有一个新的 Dispose 方法,他们在该方法中调用对象上的组件 Dispose。他们还对非托管资源使用 Kernel32 方法 CloseHandle。这个方法有什么用?在处理它时,我从未将它用于我的 SqlConnection(这也是一种非托管资源)。

http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize(v=vs.110).aspx

有人能帮我简单地理解一下上面的三个问题吗?我只是在学习所有这些。谢谢

最佳答案

首先:

public void Dispose() { }

一个 body ——它只是一个空的 body 。这里没有区别。实际上,尽管 Component.Dispose 是:

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

这个想法是,如果您想添加逻辑,您可以覆盖 protected virtual void Dispose(bool disposing) 方法。

其次,如果您像那样调用 connection.Dispose(),那么您就做错了。您应该使用 using block :

using(var conn = ...)
{
    conn.Open();
    using(var cmd = conn.CreateCommand())
    {
        // etc etc
    }
    // look ma, no finally
}

您的第三点以及您引用的 MSDN 文章只是您可能实际需要执行此操作的示例。 CloseHandle 方法只是一个非托管资源 的示例。这很关键,因为您不使用终结器来清理托管资源 - 只有未管理的资源。因此,涉及非托管句柄的示例只是一个说明的借口:

  • 从终结器调用 Dispose(false)
  • 覆盖 Dispose(bool) 方法
  • 让一些代码(句柄)从终结器和处置器中清除(分别为 Dispose(false)Dispose(true))
  • 有一些代码只在 Dispose(true) 情况下执行 - 即向前处置

关于c# - Component类库中实现的Dispose方法在哪里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19894454/

相关文章:

c# - WCF 4 Rest获取请求的IP?

c# - HashSet<T>.Contains() 对于大型列表、多线程是否高效?

c# - 何时调用 WebResponse.Close()

c# - 在 .NET Web API 中重用与 Dapper 的数据库连接

asp.net-mvc-3 - 如何使用 .net 将文件上传到 RackSpace 云文件?

image - C# : Fast and Smart algorithm to Compare two byte array (image)

.net - protobuf -net 不知道如何序列化类型为 object 的数据成员

c# - 密码过期时如何在事件目录中更改密码

c# - 如何从 FFT 数据中提取 'features'

c# - Visual Studio 2010 - 有什么方法可以获取用户控件(.ascx 文件)并编译为 DLL?