如何使用Rx.Net编写条件样本组合子

时间:2017-03-20 08:44:03

标签: c# system.reactive

我有一种情况,我希望对一个可观察的样本进行抽样,但考虑到具体条件,我希望接受每个事件。这是我的尝试,但我感觉这是不安全的,因为不断重新订阅主序列。例如,如果采样保持打开和关闭,主序列总是在订阅时生成一个值,那么我想我会一直得到重复的事件。

IObservable<T>
SampleMaybe<T>
    ( this IObservable<T> @this
    , IObservable<<IObservable<T>>> sample  
    )
{
    return sample
        .Select(s => s != null ? @this.Sample(s) : @this)
        .Switch();
}

2 个答案:

答案 0 :(得分:2)

我不确定你的.Sample(s)电话。我认为三元运算符的两个方面最终都是一样的。

话虽如此,我认为您的原始方法是可靠的,只要订阅没有副作用。这是维护订阅的示例,因此您甚至可以避免这种情况:

public static IObservable<T> SampleSometimes<T>(this IObservable<T> source, TimeSpan sampleTime, IObservable<bool> isSamplingOn)
{
    return source.Publish(_source => _source
        .Sample(sampleTime)
        .Publish( _sampled => isSamplingOn
            .Select(b => b? _sampled : _source)
            .Switch()
        )
    );
}

答案 1 :(得分:0)

这是尝试使用主题。它通过使用主题订阅原始序列,然后使用主题在问题中提供原始采样逻辑来保持原始序列。

public static IObservable<T> Sample<T>
   ( this IObservable<T> @this
   , IObservable<IObservable<T>> sample
   )  
{
    return Observable.Create<T>(observer =>
    {
        var s = new Subject<T>();
        var d0 = sample
            .Select(s1 => s1 != null ? s.Sample(s1) : s)
            .Switch()
            .Subscribe(observer.OnNext);
        var d1 = @this.Subscribe(v => s.OnNext(v));
        return new CompositeDisposable(d0,d1);
    });

}