В чем разница между SubscribeOn и ObserveOn
Я только что обнаружил SubscribeOn, который заставляет меня задаться вопросом, если я должен использовать вместо ObserveOn. Google приняла меня здесь и здесь, но ни один из них не помог мне Грок разница: это кажется невероятно тонким.
(в моем контексте у меня есть события, которые "появляются" в потоке без gui, и мне нужно переключиться на поток gui перед использованием данных событий для обновления элементов управления).
3 ответов:
у меня была похожая проблема некоторое время назад и попросил этой вопрос об этом. Я думаю, что ответы (включая комментарии) там ответят на ваш вопрос. Подводя итог:
- если вы хотите обновить элементы управления в потоке gui, используйте
ObserveOn. Если вы ссылаетесьSystem.Reactive.Windows.Forms.dllвы получаете.ObserveOn(form)что очень удобно.SubscribeOnуправляет потоком, на котором происходит фактический вызов для подписки. Проблема решена здесь заключается в том, что WinForms и WPF будут бросать исключения при добавлении обработчиков событий из нескольких различных потоков.и этой сообщение было очень полезно в выяснении отношений между
ObserveOnиSubscribeOn.
это помогло мне понять это, думая о
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));вывод выше:
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 (для синхронизации обновлений пользовательского интерфейса). Так что ты хочешь .Наблюдайте за потоком GUI.
различия в основном заключаются в том, что subscribeOn заставляет весь конвейер обрабатываться другим потоком, но с observerOn только шаги в вашем конвейере определяются после того, как observerOn будет работать в другом потоке только после того, как вы установите его будет выполняться в другом потоке.
Observable.just(1) .map ---> executed in Main thread .filter ---> executed in Main thread .subscribeOn(Scheduers.io) .subscribe()все шаги конвейера будут выполнены в другом потоке.
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()

Comments