我们必须为托管代码调用dispose方法的确切条件是什么

时间:2016-07-27 11:26:48

标签: c# dispose

我对C#中的dispose和finalizer有一些疑问,我在下面提到: -

1.除了非托管资源之外,使用dispose方法的确切需要是什么。如果有垃圾收集器释放内存,我们为什么要使用dispose来释放托管代码的内存。

2.另外,为什么不建议使用终结器.Microsoft有一些理由来开发终结器功能。在我访问的大多数网站中,建议不建议使用终结器。是什么原因。

3.有时,我们只使用object.dispose来释放,而有时我们使用idisposable接口。为什么呢?

4.我们必须调用dispose方法的确切条件是什么?

1 个答案:

答案 0 :(得分:0)

对于#1 :正如您在问题上正确写的那样,使用 Dispose 的主要原因是从非托管资源中释放资源(如文件句柄,数据库连接)等等,但还有一个案例,我们可以调用dispose来做一些与托管资源相关的事情,那就是断开事件处理程序。关于这个here有一个非常好的解释。

回答#2 ,建议不要使用终结器,因为它们会引入性能问题,因此,如果您可以使用更好的解决方案,则应避免使用它们。正如Bill Wagner在“Effective C#”中的fragment中所述:

  

终结器是一种防御机制,可以始终确保您的对象   有办法释放非托管资源

如果你继续阅读......

  

终结器是保证非托管资源的唯一方法   由给定类型的对象分配的最终被释放。但   终结者在不确定的时间执行,所以你的设计和   编码实践应尽量减少创建终结器的需要,并且   也最大限度地减少了执行现有终结器的需要。

所以终结器似乎是你唯一能做的就是确保非托管资源被释放,所以也许这就是你要找的原因(我真的不知道微软的理由,对不起)。

要回答#3 ,我需要一个确切的代码示例来表达您的真实含义,但我会尝试猜测。我想你正在讨论接下来的两种不同场景:

  • 使用它后,以显式方式调用 myObject.Dispose()。例如,我们可以创建一个实例,使用它然后调用 Dispose

    myObject = new MyObject()
    
    // More code here...
    
    myObject.Dispose();
    

    如果您确定在创建实例和调用 Dispose 方法之间,代码中没有异常,这可能会导致调用 Dispose 错过了。当然,您始终可以使用 finally 块:

    try {
      MyObject myObject = new MyObject()
      (...)
    
    }
    catch (Exception) {
      // manage exception
    }
    finally {
      if (myObject != null)
        myObject.Dispose();
    }
    
  • 通过使用使用 IDisposable 界面调用 Dispose 。它与之前的finally块基本相同,但它将“自动”创建:

    using (MyObject myObject = new MyObject()) {
       // your code here
    }
    

您可以查看docs here

回答你的#4 。我认为这是good answer,但不要忘记阅读评论。因此,简而言之,如果它具有 Dispose 方法,则应该调用它。