【发布时间】:2013-10-24 01:33:08
【问题描述】:
我看到很多这样的代码:
public class MyWcfService : IMySerciceContract, IDisposable
{
private DatabaseOperations _dataAccess;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
_dataAccess.Dispose();
}
}
MyWcfService 类将托管在 IIS 或 WAS 中,没有人会在其中显式调用 Dispose。我的想法是让这个类实现 IDisposable 是没有意义的,你最好将 _dataAccess 的使用包装在 using 语句中。据我了解,实现 IDisposable 的类的期望是该类的用户将在 using 块声明中实例化它。考虑到没有用户会显式调用 Dispose,上述示例是否是不好的做法?如果我们像上面的例子那样依赖 GC 来清理,那么 GC 到底是调用 Dispose,还是只是调用 finalizer?
【问题讨论】:
-
因为您有一个实现 IDisposable 的成员,所以理想情况下应该实现它...因为您的班级已成为所有者。请参阅 stackoverflow.com/questions/9472304/… ... 和 stackoverflow.com/questions/10956140/… ... 并运行 FXCop 以检测任何 IDisposable 违规。显然,任何使用您的类型的东西都需要调用 Dispose(显式或通过 using 隐式调用)。
-
GC 对 Dispose 或 IDisposable 一无所知。它只是调用终结器。
-
但是在这样的服务类的情况下,我们甚至不期望调用 Dispose 的东西,这有什么意义呢?如果我知道没有人会真正调用 Dispose,我为什么要实现 IDisposable?我自己在这个服务类中清理 _dataAccess 不是更好吗?
-
这就是为什么“推荐”的做法是在终结器中调用
Dispose(false)。虽然对象 应该 被直接释放(通常由创建所述实例的人;在这种情况下,它应该是 WCF 主机,因此可以愉快地忽略终结器位),稍后运行通常比 running-never 更好。 -
"DatabaseOperations _dataAccess" 是一个类成员,由你的类“拥有”。它是 IDisposable,所以你的班级也应该是。如果 _dataAccess 是类方法中的局部变量,您在方法范围内使用并丢弃了它,那么 using 块将是合适的。