在公开开始/结束方法的类中实现 ID是可操作的

本文关键字:实现 ID 可操作 方法 开始 结束 | 更新日期: 2023-09-27 17:56:22

假设我有一个类,它使用标准的开始/结束模式公开BeginLongOperation()EndLongOperation()方法,并实现IDisposable

我的班级是否负责处理对BeginLongOperation()EndLongOperation()调用之间的Dispose()调用?

如果是这样,正确的方法是什么?

在公开开始/结束方法的类中实现 ID是可操作的

我的类是否负责处理 Dispose() 之间的调用 调用 BeginLongOperation() 和 EndLongOperation()?

不,正确处置它是类的调用方的责任。这可以通过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"));

我假设开始/结束方法是异步的。或者,可以从另一个线程操作您的对象。

首先,您需要确定是否确实需要释放类的实例。如果是这样,你需要设计你的Dispose()方法(你的类应该实现IDisposable接口),这样它就不会干扰正在执行的长操作。好吧,这取决于您要实现的策略:是要等待长操作完成,还是调用 Dispose() 方法应该中断长操作?

通常你从不从类的内部代码中调用Dispose()方法,但实际上你需要保护Dispose()调用免受不当使用。

所以我认为你有责任保护你的代码免受任何可能的情况的影响,即使是在开始和结束之间发生(不需要的)调用。

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

你不应该在 using 块中声明此类的对象,而应该尝试手动释放它。

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

IDisposable 背后的想法如下,我认为这也回答了您的问题。

此接口的主要用途是释放非托管资源。当不再使用托管对象时,垃圾回收器会自动释放分配给该对象的内存。但是,无法预测何时进行垃圾回收。此外,垃圾回收器不知道非托管资源,例如窗口句柄或打开的文件和流。

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

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