.net Observable 'ObserveOn' фоновый поток - PullRequest
8 голосов
/ 24 января 2012

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

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 во всем пуле потоков, я хочу убедиться, что они работают в правильном порядкев том же потоке.

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

Кроме того, есть несколько примечательных примеров кода, использующих класс Observable для реализации этого шаблона

Ответы [ 2 ]

16 голосов
/ 24 января 2012

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

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

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

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

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

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

5 голосов
/ 24 января 2012

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

...