Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I just discovered SubscribeOn, which makes me wonder if I should be using that instead of ObserveOn. Google took me here and here, but neither have helped me grok the difference: it seems incredibly subtle.

(In my context, I've got events 'coming up' on a non-gui thread, and I need to switch over to a gui thread before using the event data to update controls).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
221 views
Welcome To Ask or Share your Answers For Others

1 Answer

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.

Subscriber thread "passed up" and Observer thread "passed down"

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...