2017-02-09 14 views
2

を実装するクラスThingがあります。別のクラスでは、Thingのコレクションがあり、そのクラスは、これらのすべてのオブザーバブルからの更新に統一的に反応する必要があります。それを行う明白な方法はObservable.Merge()であり、それは一般的に動作します。 の場合、コレクションが変更された場合、マージされたサブスクリプションで新しいThingを購読する必要があります(理論的には削除されたすべての購読を取り消しますが、問題は少ないようです) 。変化する観測値のコレクションをマージする

現在のところ、コレクションの変更ごとにサブスクリプションを再作成することでこれを達成していますが、これは処理オーバーヘッドの点では最適ではないようです。また、サブスクリプションを破棄する間の短い時間内にThing (実際に問題があることが判明しました。特にサブタイトルを短い時間でBuffer()にする必要があり、サブスクリプションの廃棄時にバッファリングされたアイテムは失われます)。

このようなオブザーバブルの変化するコレクションをマージする適切な方法は何ですか?

+0

Thing Observablesを保持するコレクションの種類は何ですか? – Shlomo

+0

@Shlomoああ、私はそれを言及すべきでした。これはObservableCollection(より正確にはCaliburn.MicroのBindableCollection)です。 – TeaDrivenDev

+2

私は 'class Thing:IObservable 'を持っていないと仮定しています。打ち間違え?あなたは 'class Thing:IObservable 'を意味するのでしょうか? – Shlomo

答えて

1

IObservable<IObservable<T>> observableがある場合、その上でMergeを呼び出すと、私のドリフトをキャッチすると、新しい親の子供が含まれます。トリックはObservableCollection<IObservable<Thing>>IObservable<IObservable<Thing>>に変換しています。

ReactiveUIが動作していて、それを使用しても問題がなければ、ObservableCollection<IObservable<Thing>>ReactiveCollection<IObservable<Thing>>に変換できます。 ReactiveCollectionObservableCollectionを継承し、IObservableも実装しています。

ReactiveUIは(私はあなたがすでにカリバーンマイクロコレクションを使用しているので、それは推測している)問題外である場合は、ObservableCollectionのイベントを使用して変換することができます:

ObservableCollection<IObservable<Thing>> observableCollection = new ObservableCollection<IObservable<Thing>>(); 
IObservable<IObservable<Thing>> oCollectionObservable = Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
    h => observableCollection.CollectionChanged += h, 
    h => observableCollection.CollectionChanged -= h 
) 
    .SelectMany(ep => ep.EventArgs.NewItems.Cast<IObservable<Thing>>()); 

ここで使用方法を示すいくつかのサンプルコードです:

次のクラスを使用して
oCollectionObservable 
    .Merge() 
    .Subscribe(t => Console.WriteLine($"Received Thing {{Id = {t.Id}}}")); 

var firstObservable = Observable.Range(1, 5) 
    .Select(i => new Thing { Id = i }) 
    .Concat(
     Observable.Range(8, 5) 
      .Select(i => new Thing { Id = i }) 
      .Delay(TimeSpan.FromSeconds(2)) 
    ); 

observableCollection.Add(firstObservable); 
var subject = new Subject<Thing>(); 
observableCollection.Add(subject); 
subject.OnNext(new Thing { Id = 6 }); 
subject.OnNext(new Thing { Id = 7 }); 

public class Thing 
{ 
    public int Id { get; set; } 
} 
関連する問題