2010-09-23 139 views
8

我有一個視圖模型,用作我的自定義控件的數據源。在視圖模型的構造函數中,我設置了一個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; 
     } 
    } 
} 
+0

會很高興知道你在用什麼語言工作;)但無論如何......一個「視圖模型」?聽起來像你是有點混合的東西,應該真的分開... – 2010-09-23 18:08:10

+0

我使用的是C#。我正在爲WPF的目錄選擇器控件工作,並且此控件必須能夠處理驅動器掛載和卸載以及cd-rom插入/刪除。由於MVVM是將UI與代碼分開的首選方式,因此我使用視圖模型返回驅動器,目錄等列表並監視驅動器。 – akonsu 2010-09-23 18:12:14

回答

4

這篇文章有解決方案:Disposing WPF User Controls

基本上,似乎WPF DOS沒有在任何地方使用IDisposable接口,讓應用程序需要清理自己明確。所以在我的情況下,我從我的控件訂閱Dispatcher.ShutdownStarted事件,該事件使用需要處理的視圖模型,並從事件處理程序中處置控件的DataContext。