予測
textBoxChanged が次のようなものによって作成されたと仮定します。
var textBoxChanged = Observable.FromEventPattern(x, "TextChanged")
.Select(evt => ((TextBox)evt.Sender).Text);
SelectMany 使用時の競合状態の防止
from... from... LINQ 内包表記は、SelectMany
使用しているものである に変換されます。Task<List<DataRecord>>
Rx は、返されたを にGetDataAsync(input)
変換するほどスマートIObservable<List<DataRecord>>
です。
問題は、最後に送信された検索要求以外の結果が返されないようにしたいということです。
これを行うには、を活用できますTakeUntil
。次の署名があります。
public static IObservable<TSource> TakeUntil<TSource, TOther>(
this IObservable<TSource> source,
IObservable<TOther> other
)
そして、他のオブザーバブル シーケンスが値を生成するまで、ソース オブザーバブル シーケンスから値を返します。
次のように使用できます。
var searchResults = from input in textBoxChanged
from results in GetDataAsync(input).ToObservable().TakeUntil(textBoxChanged)
select results;
これにより、競合状態が回避されますが、textBoxChanged に 2 回登録されます。
Switch
代わりに使用する
Switch()
二重サブスクリプションも処理するオペレーターを使用して別のアプローチが導入されたのは非常に便利なパターンです。
を使用する代わりにSelectMany
、入力を検索クエリに直接射影するだけです。これIObservable<IObservable<List<DataRecord>>
により、ストリームのストリームである の戻り値の型が得られます。Switch はストリームからストリームへとジャンプし、最新のストリームのみを返します。これは、SelectMany/TakeUntil コンボと同等です。
var searchResults = (from input in textBoxChanged
select GetSearchResults(input).ToObservable())
.Switch();
これについて詳しく説明している Rx ハンズオン ラボを参照することを強くお勧めします。