假设我有一个类,它公开了使用标准的Begin/End模式的BeginLongOperation()
和EndLongOperation()
方法,并实现了IDisposable
接口。
那么,在调用BeginLongOperation()
和EndLongOperation()
之间,是否需要我的类处理对Dispose()
的调用呢?
如果是这样的话,应该如何正确地处理呢?
var client = new WebClient();
client.DownloadStringCompleted += (sender, e) =>
{
try
{
if (e.Error == null)
{
Console.WriteLine(e.Result);
}
}
finally
{
((WebClient)sender).Dispose();
}
};
client.DownloadStringAsync(new Uri("http://www.google.com"));
我认为Begin/End方法是异步的,或者您的对象可以被另一个线程操作。
首先,您需要确定是否真的需要处理您的类的实例。如果需要,您需要设计您的Dispose()方法(您的类应该实现IDisposable接口),以使其不会干扰正在执行的长时间操作。好吧,这取决于您想要实现什么策略:您是想等待长时间操作完成,还是调用Dispose()方法应该中断长时间操作?
通常情况下,您从类内部代码中永远不会调用Dispose()方法,但确实需要保护Dispose()调用免受不适当的使用。
所以我认为保护您的代码免受任何可能的情况,甚至在Begin和End之间(不希望的)调用也是您的责任。
稍后编辑:当然,正如其他人在这里告诉你的那样,你的类的用户有责任正确使用它,但我不会依赖于此。如您所知,当对您的对象的最后一个引用消失时,您的对象将受到垃圾回收的影响。即使在非异步/单线程设计中,这种不良使用模式也可能导致在Start / End之间调用Dispose()。
不应该在 using 块内声明此类对象,而是尝试手动处理它。
您可以在使用此对象的类中的 EndLongOperation 处理程序中调用此类的 dispose 方法。
IDisposable 的理念如下,我认为这也回答了你的问题。
此接口的主要用途是释放非托管资源。当不再使用某个托管对象时,垃圾回收器会自动释放分配给该对象的内存。然而,无法预测垃圾回收将何时发生。此外,垃圾回收器对于非托管资源(如窗口句柄或打开的文件和流)没有任何知识。
使用此接口的 Dispose 方法与垃圾回收器一起显式释放非托管资源。当不再需要对象时,对象的使用者可以调用此方法。
因此,使用您的类的开发人员有责任调用 Dispose()。