在公开开始/结束方法的类中实现 ID是可操作的
本文关键字:实现 ID 可操作 方法 开始 结束 | 更新日期: 2023-09-27 17:56:22
假设我有一个类,它使用标准的开始/结束模式公开BeginLongOperation()
和EndLongOperation()
方法,并实现IDisposable
。
我的班级是否负责处理对BeginLongOperation()
和EndLongOperation()
调用之间的Dispose()
调用?
如果是这样,正确的方法是什么?
我的类是否负责处理 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()的开发人员的职责。