C# 如何用Rx.Net编写条件样本组合器

C# 如何用Rx.Net编写条件样本组合器,c#,system.reactive,C#,System.reactive,我有一种情况,我希望取样一个可观察的,但给定具体条件,我愿意接受每一个事件。这是我的尝试,但我觉得这是不安全的,因为不断重新订阅的主要序列。例如,如果采样一直处于打开和关闭状态,并且主序列总是在订阅时生成一个值,那么我认为我将一直获得重复的事件 IObservable<T> SampleMaybe<T> ( this IObservable<T> @this , IObservable<<IObservable<T>&g

我有一种情况,我希望取样一个可观察的,但给定具体条件,我愿意接受每一个事件。这是我的尝试,但我觉得这是不安全的,因为不断重新订阅的主要序列。例如,如果采样一直处于打开和关闭状态,并且主序列总是在订阅时生成一个值,那么我认为我将一直获得重复的事件

IObservable<T>
SampleMaybe<T>
    ( this IObservable<T> @this
    , IObservable<<IObservable<T>>> sample  
    )
{
    return sample
        .Select(s => s != null ? @this.Sample(s) : @this)
        .Switch();
}
IObservable
样本也许
(这是我能看到的@这
,IObservable样本
)
{
回样
.Select(s=>s!=null?@this.Sample:@this)
.开关();
}

下面是一个使用主题的尝试。它通过向原始序列订阅一个主题,然后使用该主题向问题中的原始采样逻辑提供数据,从而保持原始序列的热状态

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);
    });

}
publicstaticiobservable示例
(这是我能看到的@这
,IObservable样本
)  
{
返回可观察的。创建(观察者=>
{
var s=新主题();
var d0=样本
.Select(s1=>s1!=null?s.Sample(s1):s)
.Switch()
.订阅(observer.OnNext);
var d1=@this.Subscribe(v=>s.OnNext(v));
返回新的CompositeDisposable(d0,d1);
});
}

我不确定您的
.Sample
电话。我认为三元运算符的两面最终是相同的

话虽如此,我认为您最初的方法是可靠的,前提是订阅没有副作用。下面是一个维护订阅的示例,因此您甚至可以避免:

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()
        )
    );
}
publicstaticiobservable-SampleSometimes(此IObservable源,TimeSpan-sampleTime,IObservable-isSamplingOn)
{
返回source.Publish(\u source=>\u source
.样本(采样时间)
.Publish(_sampled=>IsSamplengon
.选择(b=>b?\u采样:\u源)
.Switch()
)
);
}