2012-01-24 102 views
6

我试图实现一个简单的观察者模式使用.net Observable类。我有一些代码,看起来像这样:.net Observable'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逻辑在除了UI线程之外的线程上执行,而不是整个线程池上的Observing,我想确保它们在同一线程上以正确的顺序运行。

以上应如何修改?

另外,在某种程度上相关的说明中,是否有任何使用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,因此您将负责处理它。您可以使用Using observable factory方法将生命周期与订阅绑定。 – Fredrick

+0

Scheduler.NewThread目前已被弃用,您应该改用NewThreadScheduler.Default。 – Kreshnik

5

.ObserveOn(Scheduler.ThreadPool)需要一个线程调度程序,它指示观察运行的线程。它看起来像您想要使用的单个线程EventLoopScheduler,而不是ThreadPool。

+0

非常感谢! – user981225

+0

Scheduler.ThreadPool已过时 – liang