SubscribeOn和ObserveOn有什么区别?
我刚刚发现了SubscribeOn
,这让我想知道是不是应该使用ObserveOn
。 谷歌把我带到这里和这里 ,但没有帮助我挖掘其中的差异:它似乎非常微妙。
(在我的上下文中,我已经在非gui线程上发生了事件,并且在使用事件数据更新控件之前,我需要切换到gui线程)。
我有一个类似的问题,回来问这个问题。 我想这里的回复(包括评论)会回答你的问题。 总结:
- 如果要更新gui线程上的控件,请使用
ObserveOn
。 如果您引用System.Reactive.Windows.Forms.dll
您将获得.ObserveOn(form)
,这是很方便的。 -
SubscribeOn
控制实际调用SubscribeOn
的线程。 这里解决的问题是,如果您从多个不同的线程添加事件处理程序,WinForms和WPF将会抛出exception。
另外, 这篇文章对于了解ObserveOn
和SubscribeOn
之间的关系非常有帮助。
它帮助我了解这一点,认为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
。
如果您将ObserveOn
行ObserveOn
,则输出为:
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()