2010-09-23 6 views
8

J'ai un modèle de vue qui est utilisé comme source de données pour mon contrôle personnalisé. Dans le constructeur du modèle de vue, j'ai mis en place un WMI ManagementEventWatcher et le démarrer. Mon modèle de vue implémente IDisposable, donc j'arrête l'observateur dans la méthode Dispose.comment nettoyer le modèle de vue correctement?

Quand je Noyez le contrôle personnalisé dans une fenêtre, puis fermez la fenêtre pour quitter l'application, il jette un InvalidComObjectException dire « objet COM qui a été séparé de son RCW sous-jacent ne peut pas être utilisé ». Cela arrive à cause de mon observateur, et si je ne le crée pas, il n'y a pas d'exception. Je ne pense pas que quelque chose garde le modèle de vue jusqu'à ce que le thread utilisé par l'observateur se termine mais avant que l'observateur ne soit arrêté, et je ne sais pas comment faire. gérer cela.

Un conseil? Merci Konstantin

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

serait agréable de savoir dans quelle langue vous travaillez avec)) mais de toute façon ... un "modèle de vue"? On dirait que vous mélangez des choses qui devraient être vraiment séparées ... –

+0

J'utilise C#. Je travaille sur un contrôle de sélecteur de répertoire pour WPF, et ce contrôle doit être capable de gérer les montages et les démontages de lecteurs, et les insertions/suppressions de cd-rom. Puisque MVVM est le moyen préféré de séparer l'interface utilisateur du code, j'utilise un modèle de vue qui renvoie la liste des lecteurs, des répertoires, etc., et surveille les lecteurs. – akonsu

Répondre

4

cet article a la solution: Disposing WPF User Controls

essentiellement, dos WPF semblent ne pas utiliser IDisposable nulle part, donc l'application doit nettoyer lui-même explicitement. Dans mon cas, je m'abonne à l'événement Dispatcher.ShutdownStarted de mon contrôle qui utilise le modèle de vue qui doit être éliminé et élimine le DataContext du contrôle depuis le gestionnaire d'événements.

Questions connexes