В чем разница между SubscribeOn и ObserveOn



Я только что обнаружил SubscribeOn, который заставляет меня задаться вопросом, если я должен использовать вместо ObserveOn. Google приняла меня здесь и здесь, но ни один из них не помог мне Грок разница: это кажется невероятно тонким.



(в моем контексте у меня есть события, которые "появляются" в потоке без gui, и мне нужно переключиться на поток gui перед использованием данных событий для обновления элементов управления).

483   3  

3 ответов:

у меня была похожая проблема некоторое время назад и попросил этой вопрос об этом. Я думаю, что ответы (включая комментарии) там ответят на ваш вопрос. Подводя итог:

  • если вы хотите обновить элементы управления в потоке gui, используйте ObserveOn. Если вы ссылаетесь System.Reactive.Windows.Forms.dll вы получаете .ObserveOn(form) что очень удобно.
  • SubscribeOn управляет потоком, на котором происходит фактический вызов для подписки. Проблема решена здесь заключается в том, что WinForms и WPF будут бросать исключения при добавлении обработчиков событий из нескольких различных потоков.

и этой сообщение было очень полезно в выяснении отношений между ObserveOn и SubscribeOn.

это помогло мне понять это, думая о SubscribeOn как установка потока, который "передается" цепочке и ObserveOn как установка потока "передается вниз" цепь.

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

в приведенном ниже коде используются именованные потоки, с которыми вы можете играть.

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

    Ничего не найдено.