如何正确清理视图模型?
问题描述:
我有一个视图模型,用作我的自定义控件的数据源。在视图模型的构造函数中,我设置了一个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;
}
}
}
答
这篇文章有解决方案:Disposing WPF User Controls
基本上,似乎WPF DOS没有在任何地方使用IDisposable接口,让应用程序需要清理自己明确。所以在我的情况下,我从我的控件订阅Dispatcher.ShutdownStarted事件,该事件使用需要处理的视图模型,并从事件处理程序中处置控件的DataContext。
会很高兴知道你在用什么语言工作;)但无论如何......一个“视图模型”?听起来像你是有点混合的东西,应该真的分开... – 2010-09-23 18:08:10
我使用的是C#。我正在为WPF的目录选择器控件工作,并且此控件必须能够处理驱动器挂载和卸载以及cd-rom插入/删除。由于MVVM是将UI与代码分开的首选方式,因此我使用视图模型返回驱动器,目录等列表并监视驱动器。 – akonsu 2010-09-23 18:12:14