public static IObservable <IList <TSource> > Buffer <TSource>(this IObservable <TSource> source, Func <TSource, int> sizeSelector, int maxSize, TimeSpan bufferTimeSpan) { BehaviorSubject <Unit> queue = new BehaviorSubject <Unit>(new Unit()); //our time-out mechanism return(source .Union(queue.Delay(bufferTimeSpan)) .ScanUnion( (list: ImmutableList <TSource> .Empty, size: 0, emitValue: (ImmutableList <TSource>)null), (state, item) => { // item handler var itemSize = sizeSelector(item); var newSize = state.size + itemSize; if (newSize > maxSize) { queue.OnNext(Unit.Default); return (ImmutableList <TSource> .Empty.Add(item), itemSize, state.list); } else { return (state.list.Add(item), newSize, null); } }, (state, _) => { // time out handler queue.OnNext(Unit.Default); return (ImmutableList <TSource> .Empty, 0, state.list); } ) .Where(t => t.emitValue != null) .Select(t => t.emitValue.ToList())); }
public static IObservable <TResult> IntervalAsync <TResult>(Func <IObservable <TResult> > f, TimeSpan period, IScheduler scheduler) { return(Observable.Create <TResult>(o => { var q = new BehaviorSubject <TimeSpan>(TimeSpan.Zero); var observable = q .Delay(t => Observable.Timer(t)) .SelectMany(_ => f()) .Do(t => q.OnNext(period)); return observable.Subscribe(o); })); }