What's the difference between SubscribeOn and ObserveOn
It helped me to understand this by thinking of SubscribeOn
as setting the thread being "passed up" the chain and ObserveOn
as setting the thread "passed down" the chain.
The code below uses named threads which you can play with.
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));
The output of the above is:
Subscribing on Thread1
Observing 1 on Thread2
It's also interesting to see that when you comment out the SubscribeOn
line, the output is:
Subscribing on Main
Observing 1 on Thread2
Because by default the subscription "passes up" whichever thread was running (Main
here). Then the ObserveOn
"passes down" Thread2
.
If you instead comment out the ObserveOn
line, the output is:
Subscribing on Thread1
Observing 1 on Thread1
Because we "pass up" the subscription on Thread1
, and by default this same thread is "passed down" and used to run the observation.
In a GUI context, to keep things responsive you want the least amount of work done on the GUI thread but you need the subscription done on the GUI thread (to synchronise UI updates). So you want to .ObserveOn the GUI thread.
I had a similar problem a while back and asked this question about it. I think the responses (including the comments) there will answer your question. To summarize:
- If you want to update controls on a gui thread, use
ObserveOn
. If you referenceSystem.Reactive.Windows.Forms.dll
you get the.ObserveOn(form)
which is handy. -
SubscribeOn
controls the thread on which the actual call to subscribe happens. The problem solved here is that WinForms and WPF will throw exceptions if you add event handlers from multiple different threads.
Also, this post was very helpful in figuring out the relationship between ObserveOn
and SubscribeOn
.