在一个暴露Begin/End方法的类中实现IDisposable

8

假设我有一个类,它公开了使用标准的Begin/End模式的BeginLongOperation()EndLongOperation()方法,并实现了IDisposable接口。

那么,在调用BeginLongOperation()EndLongOperation()之间,是否需要我的类处理对Dispose()的调用呢?

如果是这样的话,应该如何正确地处理呢?

4个回答

4
“在调用BeginLongOperation()和EndLongOperation()方法之间,处理Dispose()方法的责任不属于您的类。正确释放资源的责任归属于您的类的调用方。可以在EndLongOperation()方法中完成资源释放操作。不能使用using语句来包装该实例,因为BeginLongOperation()方法会立即返回。”
“以下是使用WebClient的示例:”
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"));

1

我认为Begin/End方法是异步的,或者您的对象可以被另一个线程操作。

首先,您需要确定是否真的需要处理您的类的实例。如果需要,您需要设计您的Dispose()方法(您的类应该实现IDisposable接口),以使其不会干扰正在执行的长时间操作。好吧,这取决于您想要实现什么策略:您是想等待长时间操作完成,还是调用Dispose()方法应该中断长时间操作?

通常情况下,您从类内部代码中永远不会调用Dispose()方法,但确实需要保护Dispose()调用免受不适当的使用。

所以我认为保护您的代码免受任何可能的情况,甚至在Begin和End之间(不希望的)调用也是您的责任。

稍后编辑:当然,正如其他人在这里告诉你的那样,你的类的用户有责任正确使用它,但我不会依赖于此。如您所知,当对您的对象的最后一个引用消失时,您的对象将受到垃圾回收的影响。即使在非异步/单线程设计中,这种不良使用模式也可能导致在Start / End之间调用Dispose()。


0

不应该在 using 块内声明此类对象,而是尝试手动处理它。

您可以在使用此对象的类中的 EndLongOperation 处理程序中调用此类的 dispose 方法。


0

IDisposable 的理念如下,我认为这也回答了你的问题。

此接口的主要用途是释放非托管资源。当不再使用某个托管对象时,垃圾回收器会自动释放分配给该对象的内存。然而,无法预测垃圾回收将何时发生。此外,垃圾回收器对于非托管资源(如窗口句柄或打开的文件和流)没有任何知识。

使用此接口的 Dispose 方法与垃圾回收器一起显式释放非托管资源。当不再需要对象时,对象的使用者可以调用此方法。

因此,使用您的类的开发人员有责任调用 Dispose()。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接