示例#1
0
        public static IObservable <IChangeSet <TObject, TKey> > DelayRemove <TObject, TKey>(this IObservable <IChangeSet <TObject, TKey> > source,
                                                                                            TimeSpan delayPeriod, Action <TObject> onDefer)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (onDefer == null)
            {
                throw new ArgumentNullException(nameof(onDefer));
            }

            return(Observable.Create <IChangeSet <TObject, TKey> >(observer =>
            {
                var locker = new object();
                IConnectableObservable <IChangeSet <TObject, TKey> > shared = source.Synchronize(locker).Publish();

                var notRemoved = shared.WhereReasonsAreNot(ChangeReason.Remove);


                var removes = shared.WhereReasonsAre(ChangeReason.Remove)
                              .Do(changes => changes.Select(change => change.Current).ForEach(onDefer))
                              .Delay(delayPeriod)
                              .Synchronize(locker);

                IDisposable subscriber = notRemoved.Merge(removes).SubscribeSafe(observer);
                return new CompositeDisposable(subscriber, shared.Connect());
            }));
        }
示例#2
0
        public static IObservable <IChangeSet <TObject> > DelayRemove <TObject>(this IObservable <IChangeSet <TObject> > source,
                                                                                TimeSpan delayPeriod, Action <TObject> onDefer)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (onDefer == null)
            {
                throw new ArgumentNullException(nameof(onDefer));
            }

            return(Observable.Create <IChangeSet <TObject> >(observer =>
            {
                ListChangeReason[] removed = new[] { ListChangeReason.Remove, ListChangeReason.Clear, ListChangeReason.RemoveRange };

                SourceList <TObject> localList = new SourceList <TObject>();

                object locker = new object();
                IConnectableObservable <IChangeSet <TObject> > shared = source.Synchronize(locker).Publish();

                IDisposable notRemoved = shared.WhereReasonsAreNot(removed)
                                         .Subscribe(changes =>
                {
                    localList.Edit(innerList =>
                    {
                        changes.ForEach(change =>
                        {
                            switch (change.Reason)
                            {
                            case ListChangeReason.Add:
                                innerList.Add(change.Item.Current);
                                break;

                            case ListChangeReason.AddRange:
                                change.Range.ForEach(innerList.Add);
                                break;

                            case ListChangeReason.Replace:
                                innerList.Replace(change.Item.Previous.Value, change.Item.Current);
                                break;
                            }
                        });
                    });
                });

                //when removed,invoke call back
                IDisposable removes = shared.WhereReasonsAre(removed)
                                      .ForEachItemChange(change => onDefer(change.Current))
                                      .Delay(delayPeriod)
                                      .Synchronize(locker)
                                      .Subscribe(changes =>
                {
                    //flatten removes into a single enumerable
                    TObject[] toRemove = changes.SelectMany(change =>
                    {
                        return change.Type == ChangeType.Item ? new[] { change.Item.Current } : change.Range.Select(t => t);
                    }).ToArray();
                    //remove in one hit
                    localList.RemoveMany(toRemove);
                });

                IDisposable subscriber = localList.Connect().SubscribeSafe(observer);
                return new CompositeDisposable(subscriber, removes, notRemoved, shared.Connect());
            }));
        }