如何正确清理视图模型?

时间:2010-09-23 18:05:12

标签: wpf mvvm wmi

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

1 个答案:

答案 0 :(得分:4)

这篇文章有解决方案:Disposing WPF User Controls

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