在c#中处置非托管对象

时间:2010-12-10 18:09:45

标签: c# dispose idisposable

假设我有一个MyCustomDatabaseAccess作为数据成员的类。 MyCustomDatabaseAccess有一个Dispose()方法。 MyCustomDatabaseAccess是访问数据库的中间件类。

public class MyClass {
   private MyCustomDatabaseAccess db_access;
}

MyClass是否需要实现IDisposable接口?

我现在的解决方案是做这样的事情:

    public class MyClass {
       private MyCustomDatabaseAccess db_access;

       public void GetDBResults () {
          db_access = new MyCustomDatabaseAccess();
          DataTable dt = db_access.ExecuteStoredProc(param1, param2, etc..);

          //do stuff with results

          db_access.Dispose();

    }

}

从我在MSDN上看到的,另一种确保正确处理此对象的方法是让MyClass实现IDisposable接口,然后实现Dispose()函数,然后在调用对象的类中调用它我的课。 有关详细信息,请参阅此 http://www.devx.com/dotnet/Article/33167/0/page/3

哪种方式更可取,为什么? 谢谢!

4 个答案:

答案 0 :(得分:2)

我建议使用以下两种方法之一:

  1. 将IDisposable对象包装在使用块中。
  2. 在类中保留对IDisposable对象的引用,并让您的类实现IDisposable。在类的Dispose方法中处理对象。
  3. 您应该选择哪个取决于对象所需的生命周期。

    • 如果您只在单个方法调用期间需要它,那么第一个选项 - 使用块 - 更可取,因为它更简单,更难出错。使用块(几乎)保证一旦不再需要对象就会为您调用Dispose - 即使在抛出异常的情况下也是如此。
    • 如果一次性对象必须持续长于单个方法调用的持续时间,那么您不能使用第一个选项,因此您应该使用第二个选项 - 即您的类应该实现IDisposable。

答案 1 :(得分:1)

如果您确实要维护与数据库的连接(并且它不仅仅是您想在此处发布的示例代码),那么您现在正在做正确的事情。那就是打开数据库连接,查询数据并关闭/处理它。

另一方面,如果您的资源占用大量内存但对于尽快关闭/处置不是时间关键,则应使用IDisposable.Dispose()方法。当你的对象不再被引用而GC需要内存时,你的对象将被收集,Dispose()方法将被关闭,它将处理你的非托管大对象。

答案 2 :(得分:1)

我认为你只需要确保你的物品被处理掉。

如果您在方法中执行此操作,即使出现意外错误,我认为您也可以。如果您坚持使用类中的非托管资源,那么实现IDisposable是一种确保在对象完成时有机会处置资源的方法,或者为用户提供明确处理资源的方法。

如果您只是在方法中创建和使用资源而不在类中保留引用,那么只要您确保将它们放在方法中(通过手动操作,或者更容易,通过包装然后在一个使用块),那么你应该没问题。

答案 3 :(得分:0)

是的,实现IDisposable就是告诉客户你的代码"嘿,你需要在这个对象上调用dispose,因为它维护了对非托管资源的引用。"