2010-04-07 8 views
3

Je reçois une exception 'UnauthorizedAccesExpection - Access Cross-thread non valide' lorsque j'essaie de déclencher un événement PropertyChanged dans un abonnement à une collection IObservable créée via Observable.Interval(). Avec mes connaissances de threads limitées, je suppose que l'intervalle se passe sur un autre thread alors que l'événement veut se passer sur le fil de l'interface utilisateur? Une explication du problème serait très utile.Comment puis-je envoyer un événement PropertyChanged d'un abonnement à un IObservable basé sur un intervalle

Le code ressemble un peu:

var subscriber = Observable.Interval(TimeSpan.FromSeconds(1)) 
       .Subscribe(x => 
       { 
        Prop = x; // setting property raises a PropertyChanged event 
       }); 

Toute solution?

Edit:

Ce code est en cours d'exécution d'un ViewModel pas DependencyObject.

Répondre

2

Modifier: Je confondais SubscribeOn avec ObserveOn. J'ai mis à jour ma réponse

Vous pouvez résoudre votre problème en mettant votre intervalle sur le fil répartiteur:

var subscriber = Observable.Interval(TimeSpan.FromSeconds(1), Scheduler.Dispatcher) 
       .Subscribe(x => 
       { 
        Prop = x; // setting property raises a PropertyChanged event 
       }); 

Sinon, vous pourriez être en mesure d'utiliser ObserveOnDispatcher mais qui impliquerait des fils sauter donc je recommander contre:

var subscriber = Observable.Interval(TimeSpan.FromSeconds(1)) 
       .ObserveOnDispatcher() 
       .Subscribe(x => 
       { 
        Prop = x; // setting property raises a PropertyChanged event 
       }); 
1

Utilisation: -

var subscriber = Observable.Interval(TimeSpan.FromSeconds(1)) 
      .Subscribe(x => 
      { 
       Dispatcher.BeginInvoke(() => Prop = x); 
      }); 

Modifier

Puisque vous devez faire de la ViewModel voir cette answer par Jeff Wilcox et son excellent blog sur le sujet: Property change notifications for multithreaded Silverlight applications.

+0

Ceci est appelé à partir d'un ViewModel pas un DependencyObject donc je n'ai pas une propriété Dispatcher. –