2012-01-24 4 views
6

J'essaye d'implémenter un modèle Observer simple en utilisant la classe .net Observable. J'ai le code qui ressemble à ceci:.net Observable 'ObserverOn' un fil de fond

Observable.FromEventPattern<PropertyChangedEventArgs>(
    Instance.User, 
    "PropertyChanged") 
      .Where(e => e.EventArgs.PropertyName == "FirstName") 
      .ObserveOn(Scheduler.ThreadPool) 
      .Subscribe(search => OnFirstNameChanged(search.EventArgs)); 

Observable.FromEventPattern<PropertyChangedEventArgs>(
    Instance.User, 
    "PropertyChanged") 
      .Where(e => e.EventArgs.PropertyName == "LastName") 
      .ObserveOn(Scheduler.ThreadPool) 
      .Subscribe(search => OnLastNameChanged(search.EventArgs)); 

Je veux que les observateurs à courir sur un fil d'arrière-plan, mais je les veux tous courir sur le même thread d'arrière-plan (pour notre mise en œuvre réelle, il sera trop compliqué à avoir chaque auditeur sur un fil différent). Je veux que toute la logique OnXXXChanged soit exécutée sur un thread autre que le thread UI, mais au lieu de Observing sur l'ensemble du pool de threads, je veux m'assurer qu'ils s'exécutent dans le bon ordre, sur le même thread.

Comment ce qui précède doit-il être modifié?

De même, sur une note quelque peu liée, y a-t-il de bons exemples de code utilisant la classe Observable pour implémenter ce modèle?

Répondre

13

Vous devez créer un EventLoopScheduler et d'utiliser cette instance unique dans tous les appels à ObserverOn:

var scheduler = new EventLoopScheduler(ts => new Thread(ts)); 

... .ObserveOn(scheduler). ... 

Le fil créé par la méthode d'usine est le fil utilisé pour planifier l'exécution sur. En laissant la propriété ExitIfEmpty définie à false, ce thread ne se terminera pas même s'il n'y a rien à faire, ce qui signifie qu'il sera réutilisé pour chaque appel.

Toutefois, vous pouvez également utiliser Scheduler.NewThread. L'utilisation de ce planificateur permettra au thread de se terminer s'il n'y a plus rien à faire. Lorsque plus de travail est mis en file d'attente par ObserverOn un nouveau thread sera créé, mais un seul thread devrait exister, ce qui signifie que vous n'avez pas synchroniser les différents observateurs. Les threads créés par EventLoopScheduler (qui est utilisé par Scheduler.NewThread) sont nommés Event Loop #. Vous verrez ces noms dans le débogueur.

+0

Super, merci beaucoup! – user981225

+1

EventLoopScheduler implémente IDisposable, vous serez donc responsable de sa mise au rebut. Vous pouvez utiliser la méthode Factory observable factory pour lier la durée de vie à l'abonnement. – Fredrick

+0

Scheduler.NewThread est maintenant obsolète, vous devez utiliser NewThreadScheduler.Default à la place. – Kreshnik

5

.ObserveOn(Scheduler.ThreadPool) prend un ordonnanceur de thread qui dicte le thread sur lequel l'observation s'exécute. Il semble que pour un seul thread que vous souhaitez utiliser EventLoopScheduler, plutôt que ThreadPool.

+0

Merci beaucoup! – user981225

+0

Scheduler.ThreadPool est devenu obsolète – liang