【发布时间】:2013-03-20 19:21:00
【问题描述】:
有没有一种方法可以在 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 对象,并将原始控制器对象附加到它上面。这些对象一旦完成就会被释放,而控制器只有在它是唯一需要释放的对象时才会被释放。
【问题讨论】:
-
你到底为什么要这么做?基本上你是在问“我有这份合同说我必须做 X,但我不想 - 我该如何摆脱它?”
-
我在这里闻到了框架滥用的味道。如果整个 .NET 框架不需要取消 Dispose() 调用,您认为您真的需要吗?
-
您将
Dispose方法与 finalizer混淆了,该方法是一种约定(在 .NET Framework 中广泛使用,但不是一种语言,只是一种约定) >(具有不同的语法),并且 仍然 你不能取消终结器(这没有意义)... "cancel"Dispose只是……不打电话给Dispose。 -
@Jcl:实际上有一种方法可以“取消”终结器。当 GC 将引用归类为“已死且需要终结”时,它会将其放入终结器队列中,此时它再次变为“活动”。如果终结器导致对该对象的引用保持活动状态,那么您再次拥有一个真正的活动对象,GC 不会清理,直到它再次死亡。 (事实上,如果对象希望终结器在第二次死亡时再次运行,它可以将自己标记为“将我视为从未终结”。)这些技术仅适用于高级玩家。
-
@Jcl:你可以用普通的 C# 来做。池化策略经常使用这种技术。当对象即将被 GC 释放时,GC 将其放入终结器队列中,当终结器运行时,它将对象重新放回池中,使其处于活动状态,并告诉对象“你还没有已完成”,以便下一次它绕过这个业力循环,它会再次复活。