SubscribeOn和ObserveOn有什么区别?

我刚刚发现了SubscribeOn ,这让我想知道是不是应该使用ObserveOn 。 谷歌把我带到这里和这里 ,但没有帮助我挖掘其中的差异:它似乎非常微妙。

(在我的上下文中,我已经在非gui线程上发生了事件,并且在使用事件数据更新控件之前,我需要切换到gui线程)。

我有一个类似的问题,回来问这个问题。 我想这里的回复(包括评论)会回答你的问题。 总结:

  • 如果要更新gui线程上的控件,请使用ObserveOn 。 如果您引用System.Reactive.Windows.Forms.dll您将获得.ObserveOn(form) ,这是很方便的。
  • SubscribeOn控制实际调用SubscribeOn的线程。 这里解决的问题是,如果您从多个不同的线程添加事件处理程序,WinForms和WPF将会抛出exception。

另外, 这篇文章对于了解ObserveOnSubscribeOn之间的关系非常有帮助。

它帮助我了解这一点,认为SubscribeOn设置线程被“传递”链, ObserveOn设置线程“传递”链。

订阅者线程“传递”和观察者线程“传递”

下面的代码使用命名线程,你可以玩。

 Thread.CurrentThread.Name = "Main"; IScheduler thread1 = new NewThreadScheduler(x => new Thread(x) { Name = "Thread1" }); IScheduler thread2 = new NewThreadScheduler(x => new Thread(x) { Name = "Thread2" }); Observable.Create<int>(o => { Console.WriteLine("Subscribing on " + Thread.CurrentThread.Name); o.OnNext(1); return Disposable.Create(() => {}); }) .SubscribeOn(thread1) .ObserveOn(thread2) .Subscribe(x => Console.WriteLine("Observing '" + x + "' on " + Thread.CurrentThread.Name)); 

以上的输出是:

Subscribing on Thread1 Observing 1 on Thread2

看到SubscribeOn行注释掉的时候,输出结果是:

Subscribing on Main Observing 1 on Thread2

因为默认情况下订阅“传递”,无论哪个线程正在运行( Main在这里)。 然后ObserveOn “传递” Thread2

如果您将ObserveOnObserveOn ,则输出为:

Subscribing on Thread1 Observing 1 on Thread1

因为我们在Thread1上“传递”订阅,默认情况下,这个同一个线程被“传递下去”并用于运行观察。

这个区别基本上是subscribeOn强制整个pipe道被另一个线程处理,但是只有在你的pipe道中定义了observerOn之后,才会在另外一个线程中运行,只有在你设置它之后才会在另一个线程中执行。

  Observable.just(1) .map ---> executed in Main thread .filter ---> executed in Main thread .subscribeOn(Scheduers.io) .subscribe() 

pipe道的所有步骤将在另一个线程中执行。

  Observable.just(1) .map ---> executed in Main thread .filter ---> executed in Main thread .observerOn(Scheduers.io) .map ---> executed in New thread .filter ---> executed in New thread .subscribe()