如果我有一个拥有托管IDisposable
对象的表单,这些对象需要在表单的生命周期内保持不变(即类级成员,也许是为了单元测试而包装和管理计时器的类) ,我什么时候应该给他们打电话Dispose()
?
为了提出问题(为了避免“GC会为你配置它”类型的答案),我们还假设我需要调用额外的关闭逻辑,例如:
Buffer.Flush()
Buffer.Dispose()
我可以将它放在我的部分类(Dispose()
)中的Form.Designer.vb
方法的现有实现中,但修改该类通常是不受欢迎的。
似乎FormClosed
或Disposed
事件是最佳选择。有理由选择一个而不是另一个吗?
答案 0 :(得分:2)
“正确”的方法是将Dispose()方法从表单的Designer.vb文件移动到表单的源代码文件并进行编辑。然而,在vb.net IDE中它很尴尬,它隐藏了该文件。您必须单击“显示所有文件”图标才能看到它。
使用FormClosed是错误的,当使用ShowDialog()显示表单时,会过早地处理对象。当您检索对话框结果时,这可能会导致ObjectDisposed异常。
使用Disposed事件很好。
答案 1 :(得分:0)
在C#winforms中,我将Dispose()
方法的实现从设计器移动到代码隐藏文件。从来没有遇到过这个问题。我猜你可以在VB中做同样的事情。
唯一重要的是保留处理Components
集合的代码。
答案 2 :(得分:0)
一般来说,您应该尽快释放非托管资源,例如使用using
语句。它通常使您的应用程序更安全,并且不会出现与资源生命周期相关的死锁和其他不当行为,而不是“习惯性地”保留资源“以防万一”或完全不必要的情况。
但是,有时您出于性能原因需要“缓存”非托管资源,或者您甚至需要出于语义原因保留一个(例如,在UI级别上互斥的一些有意锁定方案)。
在这些情况下,从父对象的Dispose
调用Dispose
是一个很好的约定。在这种情况下,通过处理Disposed
事件。
FormClosed
风险更大,因为另一个处理程序可能会阻止关闭,或者父表单的处理程序代码可能会调用此表单的方法,并且您最终可能会使用已处置的资源。再加上在整个表单上直接调用Dispose
时永不释放资源的风险。
将任何代码放到FormClosed
的主要优点是“更健全”的操作环境,尤其是访问父窗体。但是,很少需要处理非托管资源。