この質問を読んだことに基づいて: SubscribeOnとObserveOnの違いは何ですか
ObserveOn
は、コードがSubscribe
ハンドラーのどこに実行されるかを設定します。
stream.Subscribe(_ => { // this code here });
SubscribeOn
メソッドは、ストリームのセットアップが行われるスレッドを設定します。
これらが明示的に設定されていない場合、TaskPoolが使用されることを理解するようになります。
私の質問は、次のようなことをすることです。
Observable.Interval(new Timespan(0, 0, 1)).Where(t => predicate(t)).SelectMany(t => lots_of(t)).ObserveOnDispatcher().Subscribe(t => some_action(t));
Where
predicate
およびSelectMany
lots_of
が実行されている場合、some_action
はディスパッチャで実行されていますか?
ジェームズの答えは非常に明確で包括的なものでした。しかし、それにもかかわらず、違いを説明しなければならないことに気づきました。
そのため、どのスケジューラーが呼び出されているかをグラフィカルに示すことができる非常にシンプルで愚かな例を作成しました。アクションをすぐに実行しますが、コンソールの色を変更するクラスMyScheduler
を作成しました。
SubscribeOn
スケジューラーからのテキスト出力は赤で出力され、ObserveOn
スケジューラーからのテキスト出力は青で出力されます。
using System;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reactive.Linq;
namespace SchedulerExample
{
class Program
{
static void Main(string[] args)
{
var mydata = new[] {"A", "B", "C", "D", "E"};
var observable = Observable.Create<string>(observer =>
{
Console.WriteLine("Observable.Create");
return mydata.ToObservable().
Subscribe(observer);
});
observable.
SubscribeOn(new MyScheduler(ConsoleColor.Red)).
ObserveOn(new MyScheduler(ConsoleColor.Blue)).
Subscribe(s => Console.WriteLine("OnNext {0}", s));
Console.ReadKey();
}
}
}
この出力:
また、MySchedulerの参照用(実際の使用には適していません):
using System;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
namespace SchedulerExample
{
class MyScheduler : IScheduler
{
private readonly ConsoleColor _colour;
public MyScheduler(ConsoleColor colour)
{
_colour = colour;
}
public IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
{
return Execute(state, action);
}
private IDisposable Execute<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
{
var tmp = Console.ForegroundColor;
Console.ForegroundColor = _colour;
action(this, state);
Console.ForegroundColor = tmp;
return Disposable.Empty;
}
public IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
{
throw new NotImplementedException();
}
public IDisposable Schedule<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action)
{
throw new NotImplementedException();
}
public DateTimeOffset Now
{
get { return DateTime.UtcNow; }
}
}
}
.SubcribeOn
内のコードが実行されているスレッドを設定するために.Subscribe
が使用されるとよく間違えます。ただし、パブリッシュとサブスクライブは陰陽のようなペアでなければならないことを覚えておいてください。 Subscribe's code
が実行される場所を設定するには、ObserveOn
を使用します。 Observable's code
が実行された場所を設定するには、SubscribeOn
を使用しました。または要約マントラ:where-what
、Subscribe-Observe
、Observe-Subscribe
。