如何在特定点重新订阅序列?

时间:2011-10-10 14:26:35

标签: c# .net system.reactive

我正在尝试解决以下问题: a)订户从IObservable接收事件一段时间。然后它取消订阅,做一些事情,然后再次订阅。在这里它应该开始从执行取消订阅的完全相同的点接收事件。 b)这种行为对于多个订户模型是合乎需要的。例如。当一个人取消订阅时,其他人应继续接受活动。

RX方面是否有任何建议?

提前致谢!

2 个答案:

答案 0 :(得分:1)

这是一种相当简单的Rx方式,可以将您想要的内容从my answer复制到this other question。我创建了一个名为Pausable的扩展方法,它接受一个源可观察对象和一个暂停或恢复可观察对象的布尔值的第二个可观察对象。

public static IObservable<T> Pausable<T>(
    this IObservable<T> source,
    IObservable<bool> pauser)
{
    return Observable.Create<T>(o =>
    {
        var paused = new SerialDisposable();
        var subscription = Observable.Publish(source, ps =>
        {
            var values = new ReplaySubject<T>();
            Func<bool, IObservable<T>> switcher = b =>
            {
                if (b)
                {
                    values.Dispose();
                    values = new ReplaySubject<T>();
                    paused.Disposable = ps.Subscribe(values);
                    return Observable.Empty<T>();
                }
                else
                {
                    return values.Concat(ps);
                }
            };

            return pauser.StartWith(false).DistinctUntilChanged()
                .Select(p => switcher(p))
                .Switch();
        }).Subscribe(o);
        return new CompositeDisposable(subscription, paused);
    });
}

可以像这样使用:

var xs = Observable.Generate(
    0,
    x => x < 100,
    x => x + 1,
    x => x,
    x => TimeSpan.FromSeconds(0.1));

var bs = new Subject<bool>();

var pxs = xs.Pausable(bs);

pxs.Subscribe(x => { /* Do stuff */ });

Thread.Sleep(500);
bs.OnNext(true);
Thread.Sleep(5000);
bs.OnNext(false);
Thread.Sleep(500);
bs.OnNext(true);
Thread.Sleep(5000);
bs.OnNext(false);

答案 1 :(得分:0)

听起来你需要一个&#34; papeable&#34;流。假设一次只有一个用户会处理这些值(而其他用户只是等待),这solution可能就是你所需要的。