有没有办法可以从Dispose方法中取消一个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
}
当使用块退出时,进度窗口关闭并被销毁。
现在我遇到这种情况下发生的事情也创建了一个进度窗口,而不是返回一个新对象并创建一个新窗口,我想返回第一个实例创建的对象,并且只有在第一个实例处理。
更新
好的,我所做的是每次Dialogs.ShowProgress()
调用创建一个新的IDisposable对象,并将原始控制器对象附加到它。这些物体一旦完成就会被处理掉,而控制器只有当它是唯一要处理的物体时才被处理掉。
答案 0 :(得分:4)
正如其他人所说,以一种可能无法真正处置的方式实施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
}
答案 1 :(得分:1)
不确定。只是不要做你应该做的任何事情来处置对象。你不需要积极做任何特别的事情。
但要小心;当某人处置某个对象时,他们希望它实际上处理掉它的非托管资源,而不是无视你并保留它们。
答案 2 :(得分:1)
我会小心这样做。如果取消在使用块的末尾处理方法,那么您已经丢失了对该对象的引用,并且您再也没有机会让它再次处理它的内容,这意味着如果您'可能会泄漏资源不小心。特别是,如果dispose方法释放对大型对象的引用,我自己也会这样做,我不想因为某种原因立即收集垃圾。我不会这样做,以跳过释放文件,数据库连接,网络套接字或其他任何无法收集垃圾的句柄。
正如评论者所指出的那样,我会尝试重构我的代码,以便通过取消处理我试图解决的任何问题都将以其他一些不那么危险的方式解决。
如果你完全确定你有一个边缘条件,你需要跳过处理,这是一种方法:
public void Dispose()
{
if(condition)
{
// do disposing stuff
}
}
答案 3 :(得分:1)
Dispose
所需的后置条件是客户端代码应该能够放弃对该对象的所有引用,而不会导致任何必要的清理未完成。如果在调用Dispose
之前适用该条件,则Dispose
方法可能合法地不执行任何操作。如果该条件不适用,Dispose
必须这样做,并且可能不合法地返回,除非或直到它[注意Dispose
不需要实际执行清理,如果它启动链清理将在稍后发生的事件]。 Dispose
接口的合同中没有任何内容允许它有时将对象保留在需要进一步清理的状态,除非它有理由相信通过其他方式进行清理。
答案 4 :(得分:0)
根据您的更新,我会这样做:
public void DoStuff()
{
DoPrepWork();
using( var controller = TheMethodYouWroteThatShouldReturnAController())
{
DoStuffOverControllerLifetime();
}
}