样本运算符重复

时间:2013-07-31 14:48:28

标签: c# system.reactive

我希望等效的示例运算符不会隐式过滤其结果流:

var ints = new Subject<int>();
var pulse = new Subject<Unit>();

ints.Sample(pulse)
    .Subscribe(Console.WriteLine);

ints.OnNext(1);
pulse.OnNext(Unit.Default);
ints.OnNext(2);
pulse.OnNext(Unit.Default);
pulse.OnNext(Unit.Default);
ints.OnNext(3);

// Prints 1, 2 instead of 1, 2, 2

我尝试加入上述示例,但在其他情况下失败(在热观察中):

public static IObservable<TIn> SampleWithRepetition<TIn, TPulse>(this IObservable<TIn> source, IObservable<TPulse> pulse)
{
    return from x in source
           join _ in pulse on source equals Observable.Empty<Unit>()
           select x;
}

是否可以在不使用基于状态的Observable.Create方法的情况下定义此类运算符?

1 个答案:

答案 0 :(得分:2)

以下运营商是基于州的;可能有一个更实用的方法

public static IObservable<TIn> SampleWithRepetition<TIn, TPulse>(this IObservable<TIn> source, IObservable<TPulse> pulse)
{
    return Observable.Create<TIn>(obs =>
        {
            var gate = new object();
            var x = new {Value = default(TIn), HasValue = false};

            return new CompositeDisposable()
                {
                    source.Subscribe(
                        y =>
                            {
                                lock (gate)
                                    x = new {Value = y, HasValue = true};
                            },
                        obs.OnError,
                        obs.OnCompleted),

                    pulse.Subscribe(
                        _ =>
                            {
                                bool hasValue = false;
                                TIn value = default(TIn);
                                lock (gate)
                                {
                                    hasValue = x.HasValue;
                                    value = x.Value;
                                }
                                if (hasValue)
                                    obs.OnNext(value);
                            },
                        obs.OnError,
                        obs.OnCompleted)
                };
        });
}

}