2012-01-24 14 views
6

Próbuję zaimplementować prosty wzorzec Obserwatora przy użyciu klasy .net Observable. Mam kodu, który wygląda tak:.net Obserwowalny 'ObserveOn' wątek tła

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)); 

chcę obserwatorzy uruchomić w wątku tła, ale chcę im wszystkim działać na tym samym wątku tła (dla naszej prawdziwej realizacji, będzie to zbyt skomplikowane mieć każdego słuchacza w innym wątku).

tj Chcę wszystkim logiki OnXXXChanged być przeprowadzone w wątku innego niż wątek UI, ale zamiast Observing na całej puli wątków, chcę mieć pewność, że działają w prawidłowej kolejności, w tym samym wątku.

Jak należy zmienić powyższe?

Co więcej, w nieco zbliżonym notatniku, czy istnieją przykłady dobrych przykładów kodu z wykorzystaniem klasy Observable do implementacji tego wzorca?

Odpowiedz

13

Należy utworzyć EventLoopScheduler i korzystania z pojedynczej instancji we wszystkich zaproszeniach do ObserverOn:

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

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

Gwint tworzony metodą fabryczną jest wątek wykorzystywane zaplanować wykonanie dalej. Pozostawiając właściwość ExitIfEmpty ustawioną na false, ten wątek nie zostanie zakończony, nawet jeśli nie ma nic do wykonania, co oznacza, że ​​będzie on ponownie użyty przy każdym połączeniu. Można również rozważyć użycie Scheduler.NewThread. Użycie tego programu planującego pozwoli na zakończenie wątku, jeśli nie ma już nic więcej do zrobienia. Kiedy więcej pracy zostanie umieszczone w kolejce przez ObserverOn, zostanie utworzony nowy wątek, ale powinien istnieć tylko jeden wątek, co oznacza, że ​​nie synchronizujesz różnych obserwatorów.

Gwinty utworzone przez EventLoopScheduler (używane przez Scheduler.NewThread) mają nazwę Event Loop #. Zobaczysz te nazwy w debugerze.

+0

Świetnie, dziękuję bardzo! – user981225

+1

EventLoopScheduler implementuje IDisposable, więc będziesz odpowiedzialny za ich usunięcie. Możesz użyć metody fabularnej Wykorzystaj obserwowalne, aby powiązać okres ważności z subskrypcją. – Fredrick

+0

Program Scheduler.NewThread jest obecnie uznany za przestarzały, należy zamiast tego użyć polecenia NewThreadScheduler.Default. – Kreshnik

5

.ObserveOn(Scheduler.ThreadPool) bierze harmonogram wątków, który dyktuje wątek, na którym działa obserwacja. Wygląda na pojedynczy wątek, który chcesz użyć EventLoopScheduler, zamiast ThreadPool.

+0

Dziękuję bardzo! – user981225

+0

Scheduler.ThreadPool został przestarzały – liang

Powiązane problemy