如何正确清理视图模型?

Posted

技术标签:

【中文标题】如何正确清理视图模型?【英文标题】:how to cleanup view model properly? 【发布时间】:2011-04-16 10:13:18 【问题描述】:

我有一个视图模型,用作我的自定义控件的数据源。在视图模型的构造函数中,我设置了一个 WMI ManagementEventWatcher 并启动它。我的视图模型实现了IDisposable,所以我在 Dispose 方法中停止了观察者。

当我将自定义控件嵌入到窗口中,然后关闭窗口以退出应用程序时,它会抛出 InvalidComObjectException 说“无法使用已与其底层 RCW 分离的 COM 对象”。这是因为我的观察者而发生的,如果我不创建它,也不例外。没有关于异常的附加信息,例如堆栈跟踪等。

我的猜测是,在观察者使用的线程终止但在观察者停止之前,某些东西会保留视图模型,我不知道如何处理。

有什么建议吗? 谢谢 康斯坦丁

public abstract class ViewModelBase : IDisposable, ...

    ...

    protected virtual void OnDispose()  

    void IDisposable.Dispose()
    
        this.OnDispose();
    


public class DirectorySelector : ViewModelBase

    private ManagementEventWatcher watcher;

    private void OnWMIEvent(object sender, EventArrivedEventArgs e)
    
        ...
    

    protected override void OnDispose()
    
        if (this.watcher != null)
        
            this.watcher.Stop();
            this.watcher = null;
        
        base.OnDispose();
    

    public DirectorySelector()
    
        try
        
            this.watcher = new ManagementEventWatcher(new WqlEventQuery(...));

            this.watcher.EventArrived += new EventArrivedEventHandler(this.OnWMIEvent);
            this.watcher.Start();
        
        catch (ManagementException)
        
            this.watcher = null;
        
    

【问题讨论】:

很高兴知道您正在使用哪种语言;)但无论如何......“视图模型”?听起来你有点混合应该真正分开的东西...... 我正在使用 C#。我正在为 WPF 开发一个目录选择器控件,该控件必须能够处理驱动器安装和卸载,以及 cd-rom 插入/删除。由于 MVVM 是从代码中分离 UI 的首选方式,因此我使用的视图模型返回驱动器、目录等列表并监视驱动器。 【参考方案1】:

这篇文章有解决办法:Disposing WPF User Controls

基本上,WPF 似乎没有在任何地方使用 IDisposable,因此应用程序需要明确地自行清理。所以在我的情况下,我从我的控件订阅 Dispatcher.ShutdownStarted 事件,该事件使用需要释放的视图模型,并从事件处理程序释放控件的 DataContext。

【讨论】:

以上是关于如何正确清理视图模型?的主要内容,如果未能解决你的问题,请参考以下文章

Qt 模型/视图:如何正确处理底层数据

solidworks工程图如何更换视图中的模型文件

Autodesk Forge 混乱的视图

ASP .NET Core 5 Razor Pages:如何正确使用局部视图并验证其模型状态?

THINKPHP里视图模型如何实现COUNT查询?

以正确的方式实现模型-视图-控制器