In both examples in code you've given UpdateUi
will always be invoked on the scheduler specified by RxApp.MainThreadScheduler
. I can say this with some certainty since ObserveOn
is a decorator that ensures the OnNext
handler of subscribers is called on the specified scheduler. See here for an in-depth analysis.
So that said, this is a bit puzzling. Either RxApp.MainThreadScheduler
is not referring to the correct dispatcher scheduler or UpdateUi
is transitioning off the dispatcher thread. The former is not unprecedented - see https://github.com/reactiveui/ReactiveUI/issues/768 where others have run into this. I have no idea what the issue was in that case. Perhaps @PaulBetts can weigh in, or you could raise an issue at https://github.com/reactiveui/. Whatever the case, I would carefully check your assumptions here since I would expect this to be a well tested area. Do you have a complete repro?
As to your specific question, the difference between Throttle(...).ObserveOn(scheduler)
and Throttle(..., scheduler)
is as follows:
In the first case when Throttle
is specified without a scheduler it will use the default platform scheduler to introduce the concurrency necessary to run it's timer - on WPF this would use a thread pool thread. So all the throttling will be done on a background thread and, due to the following ObserveOn
the released events only will be passed to the subscriber on the specified scheduler.
In the case where Throttle
specifies a scheduler, the throttling is done on that scheduler - both suppressed events and released events will be managed on that scheduler and the subscriber will be called on that same scheduler too.
So either way, the UpdateUi
will be called on the RxApp.MainThreadScheduler
.
You are best off throttling ui events on the dispatcher in most cases since it's generally more costly to run separate timers on a background thread and pay for the context switch if only a fraction of events are going to make it through the throttle.
So, just to check you haven't run into an issue with RxApp.MainThreadScheduler
, I would try specifying the scheduler or SynchronizationContext
explicitly via another means. How to do this will depend on the platform you are on - ObserveOnDispatcher()
is hopefully available, or use a suitable ObserveOn
overload. There are options for controls, syncronizationcontexts and schedulers given the correct Rx
libraries are imported.
MainThreadScheduler
(see https://mcmap.net/q/1667017/-the-difference-between-rx-throttle-observeon-scheduler-and-throttle-scheduler) – Tarnetgaronne