ここにあるものは、単に競合状態です。我々はすべてのコードをバックリッピング場合
はちょうど
var emitter = new Subject<string>();
emitter.OnNext("one");
emitter.OnCompleted();
var subscription = emitter
.Subscribe(
item => Console.WriteLine(item),
error => Console.WriteLine(error),
() => Console.WriteLine("Complete!")
);
Console.WriteLine("DONE.");
Console.ReadLine();
私たちは、同じ結果を取得します。 Subject<T>
を使用すると、キャッシング動作は発生しませんが、OnCompleted
通知は例外です。
SubscribeOn
オペレータは、提供されたIScheduler
インスタンスで行われるすべてのサブスクリプション作業をスケジュールします。 Subject<T>
に加入している場合は、ほとんど行われていません。 コールバックのリストにコールバックを登録するのと同じくらい簡単です。
NewThreadScheduler
にスケジュールを設定すると、新しいスレッドが作成され、スケジュールされた作業を処理する内部イベントループが作成されます。 これはかなり速いですが、新しいスレッド、EventloopSchedulerを作成し、新しいスレッドへのコンテキスト切り替えを実行する必要があります。
この例では、TestScheduler
にOnNext
とOnCompleted
の通知をスケジュールしています。 SubscribeOn
の場合はNewThreadScheduler
です。 それに続いて、TestScheduler
インスタンスのすべてのスケジュールされた作業を処理し始めます。 の処理は実質的にです。予定されている項目を繰り返して、代理人を出して仮想時計を進めるだけです。 これは信じられないほど速いです。より具体的には
、以下のコードは、ここでは単純に(契約者またはオブザーバーそれらを呼び出す)コールバックアクションのリストを持っているあなたは
var newThreadScheduler = new NewThreadScheduler();
var callbacks = new List<Action<string>>();
newThreadScheduler.Schedule(()=>callbacks.Add(str=>Console.WriteLine(str)));
foreach (var callback in callbacks)
{
callback("one");
}
Console.WriteLine("Done");
を書かれているものに似ています。 新しいスレッドで、これらのコールバックの1つの追加を非同期にスケジュールします。 そして、直ちにコールバックを反復し、文字列 "one"をそれぞれに送ります。メインスレッドがコレクションを反復処理することができる前に は結果が
Done
NewThreadScheduler
はちょうど、新しいスレッドを起動し、アクションをスケジュールし、そのアクションを実行するのに十分な時間を与えられていませんさ。
したがって、私があなたに従わなかったと考える2つのガイドラインがあります: 1)被験者;-) 2)スレッドとユニットテストを混在させないでください。これをテストしているので、TestScheduler
の存在が想定されます。ただし、TestScheduler
という2つのインスタンスを使用できます。背景と前景のインスタンス。
もっと役立つように、テストから2番目のスケジューラを削除することを提案する肯定的な指針を提供します。 SubscribeOn
演算子のTestScheduler
インスタンスを使用してください。
次は、TestScheduler
の観測可能なシーケンスファクトリメソッド(CreateColdObservable
)を使用して、件名+スケジューリングの使用を置き換えることをお勧めします。 最後に、Start
メソッドを使用するだけで、speicifc時間が1秒になると何かが得られるかどうかはわかりません。 私はそれが魔法の値1の騒音と使用を減らすと思います。
var testScheduler = new TestScheduler();
var source = testScheduler.CreateColdObservable<string>(
ReactiveTest.OnNext(TimeSpan.FromSeconds(0.1).Ticks, "one"),
ReactiveTest.OnCompleted<string>(TimeSpan.FromSeconds(0.2).Ticks));
var subscription = source.SubscribeOn(testScheduler)
.Subscribe(
item => Console.WriteLine(item),
error => Console.WriteLine(error),
() => Console.WriteLine("Complete!")
);
testScheduler.Start();
Console.WriteLine("DONE.");
Console.ReadLine();
唯一の問題は、SubscribeOn
コールがかなり冗長であることです。
FYI:NewThreadScheduler
のコード - 私は反応性の何も知らないが、あなたのコードを見て https://github.com/Reactive-Extensions/Rx.NET/blob/master/Rx.NET/Source/System.Reactive.PlatformServices/Reactive/Concurrency/NewThreadScheduler.cs
は、あなたがnewThreadScheduler' 'に加入しますが、あなたの仕事とスケジュールのすべてが' testScheduler'に対してトリガされます。 – TyCobb