Pause and Resume Subscription on cold IObservable

后端 未结 4 512
南笙
南笙 2020-12-03 03:45

Using Rx, I desire pause and resume functionality in the following code:

How to implement Pause() and Resume() ?

    static IDisposable _subscripti         


        
4条回答
  •  甜味超标
    2020-12-03 04:24

    Here's a reasonably simple Rx way to do what you want. I've created an extension method called Pausable that takes a source observable and a second observable of boolean that pauses or resumes the observable.

    public static IObservable Pausable(
        this IObservable source,
        IObservable pauser)
    {
        return Observable.Create(o =>
        {
            var paused = new SerialDisposable();
            var subscription = Observable.Publish(source, ps =>
            {
                var values = new ReplaySubject();
                Func> switcher = b =>
                {
                    if (b)
                    {
                        values.Dispose();
                        values = new ReplaySubject();
                        paused.Disposable = ps.Subscribe(values);
                        return Observable.Empty();
                    }
                    else
                    {
                        return values.Concat(ps);
                    }
                };
    
                return pauser.StartWith(false).DistinctUntilChanged()
                    .Select(p => switcher(p))
                    .Switch();
            }).Subscribe(o);
            return new CompositeDisposable(subscription, paused);
        });
    }
    

    It can be used like this:

    var xs = Observable.Generate(
        0,
        x => x < 100,
        x => x + 1,
        x => x,
        x => TimeSpan.FromSeconds(0.1));
    
    var bs = new Subject();
    
    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);
    

    It should be fairly easy for you to put this in your code with the Pause & Resume methods.

提交回复
热议问题