以下の簡単なプログラムを考えてみましょう。これは整数の観測可能性を持ち、直近に公表された整数が偶数か奇数かを計算する関数を持っています。予期しないことに、プログラムは番号が変更されたことを報告する前に最新の番号が偶数か奇数かを報告します。関数の入出力をどのように相関させるか?
static void Main(string[] args) {
int version = 0;
var numbers = new Subject<int>();
IObservable<bool> isNumberEven = numbers.Select(i => i % 2 == 0);
isNumberEven
.Select(i => new { IsEven = i, Version = Interlocked.Increment(ref version) })
.Subscribe(i => Console.WriteLine($"Time {i.Version} : {i.IsEven}"));
numbers
.Select(i => new { Number = i, Version = Interlocked.Increment(ref version) })
.Subscribe(i => Console.WriteLine($"Time {i.Version} : {i.Number}"));
numbers.OnNext(1);
numbers.OnNext(2);
numbers.OnNext(3);
Console.ReadLine();
}
出力は次のようになります。
Time 1 : False
Time 2 : 1
Time 3 : True
Time 4 : 2
Time 5 : False
Time 6 : 3
私は数を変更すると下流効果のカスケードをオフに設定しますと、これらは、彼らが起こるために報告されるだろうと思いました。サブスクリプション注文を交換すると、結果が報告される方法が入れ替わります。私はrxは非同期であり、物事が非決定的な順序で起こる可能性があることを理解しています。私の機能で.Delay()やWeb呼び出しを使用した場合、結果がいつ報告されるかわかりません。しかし、この状況では、私は非常に驚いています。
なぜこれは大きな問題ですか?これは、関数の入力と出力を関連づけようとすると(印刷番号が奇数か奇数かにかかわらず)、出力結果に入力パラメータを含める必要があります。
var isNumberEven = numbers.Select(i => new {
Number = i,
IsEven = i % 2 == 0
});
私は、小さな単純な関数の束を構築し、rx演算子を使って洗練された計算を行うことができると考えました。しかし、結果を結合/結合/相関させるためにrx演算子を使用することはできません。私は各機能を定義するときに入力と出力を関連付ける必要があります。
場合によっては、rx演算子を使用して結果を関連付けることができます。すべての入力が出力を生成したら、私はその2つを圧縮することができます。しかし、あなたが入力を調整するようなことをするとすぐに、それはもはや機能しません。
このバージョンのプログラムは、数値が妥当な方法で偶数であるか奇数であるかを報告しているようです。
static void Main(string[] args) {
var numbers = new Subject<int>();
var isNumberEven = numbers.Select(i => i % 2 == 0);
var publishedNumbers = numbers.Publish().RefCount();
var report =
publishedNumbers
.GroupJoin(
isNumberEven,
(_) => publishedNumbers,
(_) => Observable.Empty<bool>(),
(n, e) => new { Number = n, IsEven = e })
.SelectMany(i => i.IsEven.Select(j => new { Number = i.Number, IsEven = j }));
report.Subscribe(i => Console.WriteLine($"{i.Number} {(i.IsEven ? "even" : "odd")}"));
numbers.OnNext(1);
numbers.OnNext(2);
numbers.OnNext(3);
Console.ReadLine();
}
出力は次のようになります。
1 odd
2 even
3 odd
しかし、これはラッキー偶然だったか、私はそれに頼ることができるかどうか私は知りません。 Rxのどのような操作が決定的な順序で行われますか?どれが予測できないのですか?結果に入力パラメータを含めるためにすべての関数を定義する必要がありますか?
などのような演算子を使用して強制的に強制的に実行することができます。私は今日あなたの本の為に99セントをアマゾンで支払った。 – JustinM
ありがとう!私は大量の利益がウェブサイトの運営をほぼカバーしていることを保証します。 –