2012-01-24 3 views
6

Я пытаюсь реализовать простой шаблон Observer, используя .net Observable класс. У меня есть код, который выглядит следующим образом:.net Наблюдаемый 'ObserveOn' фоновый поток

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

Я хочу наблюдателей работать на фоне потока, но я хочу их всех работать на одной и той же фоновый поток (для нашей реальной реализации, это будет слишком сложно иметь каждого слушателя в другом потоке).

т.е. я хочу все OnXXXChanged логики должны выполняться в потоке, отличном от потока пользовательского интерфейса, но вместо Observing по всей ThreadPool, я хочу, чтобы убедиться, что они работают в правильном порядке, в том же потоке.

Как следует изменить вышеуказанное?

Кроме того, в некоторой смежной заметке есть ли примеры хорошего примера кода с использованием класса Observable для реализации этого шаблона?

ответ

13

Вы должны создать EventLoopScheduler и использовать этот единственный экземпляр во всех вызовах ObserverOn:

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

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

нить, созданная фабричным методом является нить используется для планирования выполнения на. Если оставить свойство ExitIfEmpty, установленное на false, этот поток не будет завершен, даже если нечего делать, чтобы он был повторно использован для каждого вызова.

Однако, вы также можете рассмотреть возможность использования Scheduler.NewThread. Использование этого планировщика позволит потоку завершить работу, если больше нечего делать. Когда больше работы помещено в очередь на ObserverOn, будет создан новый поток, но только один поток должен существовать, означая, что у вас нет синхронизации разных наблюдателей.

Потоки, созданные EventLoopScheduler (используется Scheduler.NewThread), имеют название Event Loop #. Вы увидите эти имена в отладчике.

+0

Отлично, спасибо большое! – user981225

+1

EventLoopScheduler реализует IDisposable, поэтому вы будете нести ответственность за его удаление. Вы можете использовать метод «Использовать наблюдаемый фабрика» для привязки времени жизни к подписке. – Fredrick

+0

Scheduler.NewThread устарел сейчас, вместо этого следует использовать NewThreadScheduler.Default. – Kreshnik

5

.ObserveOn(Scheduler.ThreadPool) принимает планировщик потоков, который диктует поток, над которым работает наблюдение. Похоже, что для одного потока вы хотите использовать EventLoopScheduler, а не ThreadPool.

+0

спасибо! – user981225

+0

Планировщик.ThreadPool был устаревшим – liang

Смежные вопросы