Ben*_*jol 70 .net system.reactive
我刚刚发现SubscribeOn,这让我想知道我是否应该使用它而不是ObserveOn.谷歌把我带到这里和这里,但都没有帮助我找到差异:它似乎非常微妙.
(在我的上下文中,我在非gui线程上发生了'事件',我需要在使用事件数据更新控件之前切换到gui线程).
Tar*_*ran 56
它帮助我通过思考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));
Run Code Online (Sandbox Code Playgroud)
以上的输出是:
Subscribing on Thread1
Observing 1 on Thread2
有趣的是,当您注释掉该SubscribeOn行时,输出为:
Subscribing on Main
Observing 1 on Thread2
因为默认情况下,订阅"传递"任何正在运行的线程(Main此处).然后ObserveOn"传下来" Thread2.
如果您注释掉该ObserveOn行,则输出为:
Subscribing on Thread1
Observing 1 on Thread1
因为我们"通过"订阅Thread1,默认情况下,这个相同的线程被"传递"并用于运行观察.
在GUI上下文中,为了保持响应,您希望在GUI线程上完成最少量的工作,但您需要在GUI线程上完成订阅(以同步UI更新).所以你想.ObserveOn GUI线程.
根本上的区别在于,subscribeOn强制整个管道由另一个线程处理,但是使用observerOn,只有在您设置管道将在observerOn之后运行的步骤之后,才能在另一个线程中执行observerOn。
Observable.just(1)
.map ---> executed in io thread
.filter ---> executed in io thread
.subscribeOn(Scheduers.io)
.subscribe()
Run Code Online (Sandbox Code Playgroud)
管道的所有步骤将在另一个线程中执行。
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()
Run Code Online (Sandbox Code Playgroud)