取消dispose方法中的dispose
本文关键字:dispose 方法 取消 | 更新日期: 2023-09-27 18:04:51
是否有一种方法可以从dispose方法中取消处置,换句话说,当a . dispose()被调用时不处置a。
我解释得不太好,因为我想不出更好的表达方式。我所拥有的是一个类,在一个单独的线程中运行的弹出窗口中显示进度条(选框)。当创建进度弹出窗口时,返回一个类似控制器的一次性对象,因此我们可以这样做:
using (var progress = Dialogs.ShowProgress("Please wait..."))
{
// do lots of stuff here
progress.UpdateStatus("Please wait some more...");
// do more stuff
}
当using块退出时,进程窗口被关闭并销毁。
现在我有一些情况,在这个块中发生的事情也创建了一个进度窗口,而不是返回一个新对象并创建一个新窗口,我想返回由第一个实例创建的对象,并且只在第一个实例被处理后才销毁它。
我所做的是用每个Dialogs.ShowProgress()
调用创建一个新的IDisposable对象,并将原始控制器对象附加到它。这些对象在它们完成的时候就会被处理掉,而控制器只有在它是唯一一个可以处理的对象的时候才会被处理。
正如其他人所说,以一种可能无法真正处理的方式实现IDisposable
是一个坏主意。这里有一种替代方法来实现您正在尝试做的事情:
interface IMaybeDisposable
{
bool TryDispose(); //return false if dispose was canceled
}
你可以这样使用:
IMaybeDisposable maybe = //something
try
{
// do something with maybe
}
finally
{
if (maybe.TryDispose())
// yay, it disposed!
else
// hm, it didn't dispose; do something else
}
当然。只是不要做任何你会做的事情来处理这个对象。你不需要主动做任何特别的事情。
不过要小心;当某人处置一个对象时,他们希望它实际处置它的非托管资源,而不是忽略您并保留它们。
Dispose
所需的后置条件是客户端代码应该能够放弃对对象的所有引用,而不会导致任何必要的清理未完成。如果在调用Dispose
之前应用该条件,那么Dispose
方法可能合法地不做任何事情。如果这个条件不成立,Dispose
必须让它这样做,并且可能不会合法返回,除非或直到它这样做[注意,Dispose
不需要实际执行清理,如果它启动了一系列事件,清理将在稍后的某个时间发生]。Dispose
接口的契约中没有任何内容允许它有时将对象留在需要进一步清理的状态,除非它有理由相信将通过其他方式进行清理。
这样做我会很小心。如果在using块的末尾取消处置方法,那么就失去了对该对象的引用,并且永远没有机会让它再次处置其内容,这意味着如果不小心,可能会泄漏资源。特别是,如果dispose方法释放了对大型对象的引用,而出于某种原因,我不希望立即收集这些对象的垃圾,那么我自己只会这样做。我不会跳过释放文件、数据库连接、网络套接字或任何其他不能被垃圾收集的句柄。
正如评论者指出的那样,我将尝试重构我的代码,以便通过取消dispose来解决的任何问题都可以通过其他不那么危险的方式来解决。
如果你绝对确定你有一个边缘条件,你需要跳过处理一些东西,这里有一种方法:
public void Dispose()
{
if(condition)
{
// do disposing stuff
}
}
根据您的更新,我会这样做:
public void DoStuff()
{
DoPrepWork();
using( var controller = TheMethodYouWroteThatShouldReturnAController())
{
DoStuffOverControllerLifetime();
}
}