В обоих приведенных вами примерах кода UpdateUi
будет всегда вызываться в планировщике, указанном RxApp.MainThreadScheduler
. Я могу сказать это с некоторой уверенностью, поскольку ObserveOn
— это декоратор, обеспечивающий вызов OnNext
обработчика подписчиков в указанном планировщике. См. здесь глубинный анализ.
Итак, это немного озадачивает. Либо RxApp.MainThreadScheduler
не относится к правильному планировщику диспетчера, либо UpdateUi
переходит из потока диспетчера. Первое не является беспрецедентным — см. https://github.com/reactiveui/ReactiveUI/issues/768 где другие столкнулись с этим. Я понятия не имею, в чем дело было в том случае. Возможно, @PaulBetts сможет внести свой вклад, или вы могли бы поднять вопрос на https://github.com/reactiveui/. В любом случае, я бы тщательно проверил ваши предположения, так как ожидаю, что это будет хорошо проверенная область. У вас есть полная копия?
Что касается вашего конкретного вопроса, разница между Throttle(...).ObserveOn(scheduler)
и Throttle(..., scheduler)
заключается в следующем:
В первом случае, когда Throttle
указан без планировщика, он будет использовать планировщик платформы по умолчанию, чтобы ввести параллелизм, необходимый для запуска его таймера - в WPF это будет использовать поток пула потоков. Таким образом, все регулирование будет выполняться в фоновом потоке, и из-за следующих ObserveOn
подписчику будут передаваться только выпущенные события в указанном планировщике.
В случае, когда Throttle
указывает планировщик, регулирование выполняется в этом планировщике — как подавленные события, так и выпущенные события будут управляться в этом планировщике, и подписчик также будет вызываться в том же планировщике.
Так что в любом случае UpdateUi
будет вызываться RxApp.MainThreadScheduler
.
В большинстве случаев лучше всего регулировать события пользовательского интерфейса в диспетчере, поскольку, как правило, более затратно запускать отдельные таймеры в фоновом потоке и платить за переключение контекста, если только часть событий собирается пройти через регулирование.
Итак, просто чтобы убедиться, что вы не столкнулись с проблемой с RxApp.MainThreadScheduler
, я бы попробовал явно указать планировщик или SynchronizationContext
другим способом. Как это сделать, будет зависеть от платформы, на которой вы работаете — надеюсь, ObserveOnDispatcher()
доступна, или используйте подходящую перегрузку ObserveOn
. Существуют параметры для элементов управления, контекстов синхронизации и планировщиков, если импортированы правильные библиотеки Rx
.
person
James World
schedule
02.03.2015