如何正确清理视图模型?

ako*_*nsu 12 wpf wmi mvvm

我有一个视图模型,用作我的自定义控件的数据源.在视图模型的构造函数中,我设置了一个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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ako*_*nsu 6

本文提供了解决方案:处置WPF用户控件

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