可能重复:
IDisposable Question
我编写了一个类并实现了IDisposable
接口。
我实现了Dispose
方法并在方法中添加了代码中断。
我的假设是,当Class因为C#Garabage集合而超出范围时会被调用。
我希望dispose方法关闭非托管资源。我认为它比调用方法LogOff()
更优雅,而不是在方法超出范围时调用它?
但它似乎没有被调用或停止在代码中断。
答案 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()。