什么时候调用Dispose方法?

时间:2011-12-09 02:12:03

标签: c# idisposable

  

可能重复:
  IDisposable Question

我编写了一个类并实现了IDisposable接口。

我实现了Dispose方法并在方法中添加了代码中断。

我的假设是,当Class因为C#Garabage集合而超出范围时会被调用。

我希望dispose方法关闭非托管资源。我认为它比调用方法LogOff()更优雅,而不是在方法超出范围时调用它?

但它似乎没有被调用或停止在代码中断。

5 个答案:

答案 0 :(得分:4)

您需要在实现IDisposable的任何对象上显式调用Dispose。如果使用using(){}代码构造,编译器将在using块的末尾自动调用Dispose。

一个好的模式是通过私有布尔字段跟踪是否已经调用dispose,如果没有从对象终结器调用它(并且也从Dispose方法调用GC.SuppressFinalize(),假设你处理所有从那里完成任务。)

答案 1 :(得分:2)

您应该考虑在using statement中将您与IDisposable课程的互动包装起来。这样做将允许您指定对象何时超出范围,并确保调用Dispose()方法。

有关正确的语法,请参阅引用的MSDN文章中的示例:

using System;

class C : IDisposable
{
    public void UseLimitedResource()
    {
        Console.WriteLine("Using limited resource...");
    }

    void IDisposable.Dispose()
    {
        Console.WriteLine("Disposing limited resource.");
    }
}

class Program
{
    static void Main()
    {
        using (C c = new C())
        {
            c.UseLimitedResource();
        }
        Console.WriteLine("Now outside using statement.");
        Console.ReadLine();
    }
}

答案 2 :(得分:1)

简短回答:调用Dispose()时会调用它。

答案很长:看看using block。这是一个语法糖,意味着与IDisposable接口一起使用,可以很好地安全地处理代码,大致等同于

Foo foo = new Foo();
try
{
    // your code that uses foo
}
finally
{
    foo.Dispose();
}

换句话说,foo保证在离开using()范围时处理。

答案 3 :(得分:0)

变量超出范围后,垃圾收集不会立即发生。 GC定期运行,.NET具有不同的垃圾收集“级别”。更频繁地收集不同级别。如果希望立即调用对象的dispose方法,则应使用using语句

using (MyClass object = new MyClass())
{
//ensures Dipose is called, even if exceptions are thrown
}

答案 4 :(得分:0)

我的假设是,当Class因为C#Garabage集合而超出范围时会被调用。

现在,垃圾收集的工作原理如何。这里有两件事:

垃圾收集 - 这会在不再有任何引用之后的某个时间清理对象。这意味着对象已超出范围(如果它们是本地人),但值得注意的是,当发生此清理时GC不会说 - 当系统决定需要运行时,它通常会懒散地发生一个集合,以释放更多的内存。在这种情况下调用清理资源的方法是终结器,它在C#中具有~Classname()形式。

IDisposable:GC的问题在于你无法控制何时调用终结器,所以IDisposable是作为一种模式引入的,当你需要在特定时间清理资源时不要使用它。想等待收集发生。由调用者代码决定是否适当调用Dispose(),没有GC支持。 C#确实有using(){}语法,这简化了这一点,并在using块的末尾自动调用Dispose()。