2017-02-09 7 views
2

IObservable<Thing>을 구현하는 클래스 Thing이 있습니다. 다른 클래스에는 Thing의 콜렉션이 있으며,이 클래스는 모든 observables의 업데이트에 통일 된 방식으로 반응해야합니다. 분명한 방법은 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 (나는 이미 Caliburn 마이크로 컬렉션을 사용하고 있기 때문에 그것이 같은데요) 문제를 벗어나면, 당신은 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 }); 

: 여기에 몇 가지 예제 코드를 보여 소용210