MVVM-light 中的清理与处置(布尔)

Posted

技术标签:

【中文标题】MVVM-light 中的清理与处置(布尔)【英文标题】:Cleanup vs Dispose(bool) in MVVM-light 【发布时间】:2011-02-27 03:14:38 【问题描述】:

在最新版本的 MVVM-light (V3 SP1) 中,ViewModel 类中的“Dispose()”和“Dispose(bool)”方法都被标记了

不要再使用这个方法了,以后的版本会去掉。改用 ICleanup.Cleanup()

这是否意味着不得在派生自 GalaSoft.MvvmLight.ViewModelBase 的所有 ViewModel 类中实现 IDisposable 接口(并且必须覆盖清理)?

如果是,则 using 不能用于视图模型实例...可能我没有理解某些内容...请澄清...这种清理有什么好处?

谢谢。

【问题讨论】:

【参考方案1】:

这个问题是历史性的。起初我认为强制所有虚拟机为 IDisposable 是个好主意。但是,IDisposable 有一个不同的意图:一旦 VM 被释放,预计(按照惯例)它将尽快被垃圾收集。与朋友交谈后,我意识到强制所有 VM 为 IDisposable 是错误的。这就是我用 ICleanup 替换 IDisposable 的原因。 ICleanup 的目的是提供一种清理 VM 的方法(例如,将它们的状态刷新到持久存储、关闭流等......),但不一定以尽快将它们作为垃圾收集的方式。

没有什么能阻止您让您的虚拟机实现 IDisposable。我只是不想在 ViewModelBase 类中保留这个约束,这就是为什么这个接口将在 V4 中删除。

拥有 ICleanup 的好处是您可以在一次调用 ViewModelLocator.Cleanup() 中清理所有虚拟机。这是对 VM 开发人员的一个提示,即 VM 应该考虑为其 VM 提供清理方法。

这有意义吗? 干杯, 洛朗

【讨论】:

感谢您的评论,如果您需要在清理后拥有可用的虚拟机,这绝对是有道理的......但我看不出有理由在不处理的情况下清理它......通常我是正在关闭虚拟机...为什么我需要在不关闭的情况下清理它?如有任何反馈,我将不胜感激。再次感谢。 @Budda 我相信 LBugnion 所说的是,他用于 IDisposable 的概念已经被尽快 GC 对象的想法所覆盖。然而,我们中的很多人一遍又一遍地使用相同的 VM 对象,因此 ViewModelBase 没有处理对象,而是提供了一个 ICleanUp 接口,其目的是擦除 VM Clean 以便它可以再次使用。如果您使用的是 VM 优先方法,这可能很有用,WPF 不会丢弃视图然后重新创建它,而是会像 VM 一样清理它。 将我的评论移至答案,这样我就可以喋喋不休。【参考方案2】:

我想我在这一点上与 Laurent 有所不同。 IDisposable 背后的想法是,对象可能需要进行一些清理,并且本身与垃圾收集没有任何关系。事实上,大部分时间 IDisposable 的实现是为了清理 GC 权限之外的非托管资源,例如文件句柄、同步对象或数据库连接。此外,仅仅因为基类实现了 IDisposable 并不意味着它必须有一个实际的实现。这可以归结为可以被派生类覆盖的虚拟 Dispose(bool disposing) 方法,以便它们可以执行清理。

正如 Budda 所暗示的,问题在于 IDisposable 按照惯例是一种单向操作。一旦一个对象被释放,它应该在它的公共方法上抛出一个 ObjectDisposedException。如果您只想清除资源以便可以重用对象,那么 Cleanup 方法是有意义的。但是,我不一定会删除 Dispose 功能,它有不同的用途。

【讨论】:

非托管资源需要在 Finalize 方法中释放。在这种情况下,您还可以强制系统在处置期间释放它们并抑制 finalize(请参阅“Dispose”方法的实现模式)【参考方案3】:

“有趣”的小故事:发现我团队中的程序员并没有退订事件,我将 IDisposable 从我们的视图模型层次结构中“清洗”下来,只是为了改变我对 Dispose 是否是正确位置的想法。

在某些情况下,由于 MEF 和我们创建视图模型的其他一些时髦方式,很难调用 Dispose。这让我怀疑它是否正确。还有一个事实是 Dispose 需要一些小心(和一个 sn-p)才能正确:

DG Update: Dispose, Finalization, and Resource Management

后来,我在一个 WP7 应用程序(我使用 MVVM Light)上做了一些周末工作,并注意到 Laurent 也改变了主意。

我认为这是正确的决定; IDisposable 发送一条消息,“客户”应尝试将类使用情况包装在 using() 中,或者尽快洗手。

最初,我同意下面帖子中接受的答案,但后来我开始认为 JaredPar 是对的。

Using IDisposable to unsubscribe events

卢克

【讨论】:

以上是关于MVVM-light 中的清理与处置(布尔)的主要内容,如果未能解决你的问题,请参考以下文章

在 CustomControl 中清理资源/处置

消息号AC305:固定资产清理科目报错

我的电脑运行VS2017 比较卡 请问大神该如何处置

电池间自燃后怎么应急处置?

既然 .NET 有一个垃圾收集器,为啥我们需要终结器/析构器/处置模式?

自定义控制和处置