I'm assuming if more than 50 values came through within 200ms then the newest would be buffered until the next timer event.
In the absence of being able to think of an elegant way to do this through composing existing operators. You could write an extension method to do this for you. The bellow solution may be a little crude. Over a long running sequence that produces lots of values you could end up with memory issues but for sequences that complete at some point it may do the job.
public static IObservable<IEnumerable<TSource>> Limit<TSource>(
this IObservable<TSource> source,
int count,
TimeSpan timeSpan,
IScheduler scheduler)
{
return Observable.Create<IEnumerable<TSource>>(
observer =>
{
var buffer = new Queue<TSource>();
var guard = new object();
var sourceSub = source
.Subscribe(x =>
{
lock (guard)
{
buffer.Enqueue(x);
}
},
observer.OnError,
observer.OnCompleted);
var timer = Observable.Interval(timeSpan, scheduler)
.Subscribe(_ =>
{
var batch = new List<TSource>();
lock (guard)
{
while (batch.Count <= count && buffer.Any())
{
batch.Add(buffer.Dequeue());
}
}
observer.OnNext(batch.AsEnumerable());
});
return new CompositeDisposable(sourceSub, timer);
});
}