With Rx, how do I ignore all-except-the-latest value when my Subscribe method is running

后端 未结 9 1572
暖寄归人
暖寄归人 2020-11-29 03:47

Using Reactive Extensions, I want to ignore messages coming from my event stream that occur while my Subscribe method is running. I.e. it sometimes takes me lon

9条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-29 04:09

    Thanks to Lee Campbell (of Intro To Rx fame), I now have a working solution using this extension method:

    public static IObservable ObserveLatestOn(this IObservable source, IScheduler scheduler)
    {
        return Observable.Create(observer =>
        {
            Notification outsideNotification = null;
            var gate = new object();
            bool active = false;
            var cancelable = new MultipleAssignmentDisposable();
            var disposable = source.Materialize().Subscribe(thisNotification =>
            {
                bool alreadyActive;
                lock (gate)
                {
                    alreadyActive = active;
                    active = true;
                    outsideNotification = thisNotification;
                }
    
                if (!alreadyActive)
                {
                    cancelable.Disposable = scheduler.Schedule(self =>
                    {
                        Notification localNotification = null;
                        lock (gate)
                        {
                            localNotification = outsideNotification;
                            outsideNotification = null;
                        }
                        localNotification.Accept(observer);
                        bool hasPendingNotification = false;
                        lock (gate)
                        {
                            hasPendingNotification = active = (outsideNotification != null);
                        }
                        if (hasPendingNotification)
                        {
                            self();
                        }
                    });
                }
            });
            return new CompositeDisposable(disposable, cancelable);
        });
    }
    

提交回复
热议问题