Skip to content

Instantly share code, notes, and snippets.

@putridparrot
Last active June 18, 2023 22:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save putridparrot/101ec42bb2863b4018d0 to your computer and use it in GitHub Desktop.
Save putridparrot/101ec42bb2863b4018d0 to your computer and use it in GitHub Desktop.
Extension to RX to add Throttling with a buffer
/*
* This code is licensed under the terms of the MIT license
*/
public static IObservable<TSource[]> ThrottleWithBuffer<TSource>(
this IObservable<TSource> source, TimeSpan timeout)
{
return source.ThrottleWithBuffer(timeout, TaskPoolScheduler.Default);
}
// see http://stackoverflow.com/questions/4655437/how-to-implement-buffering-with-timeout-in-rx
// Ripped off/based on the above answer to a StackOverflow question, I preferred the name
// ThrottleWithBuffer also.
//
// Implements throttle-like functionality, but instead of only returning the last item
// before the throttle timeout, it keeps a buffer of the items
public static IObservable<TSource[]> ThrottleWithBuffer<TSource>(this IObservable<TSource> source,
TimeSpan timeout, IScheduler scheduler)
{
return Observable.Create<TSource[]>(o =>
{
var buffer = new SynchronizedCollection<TSource>();
var timeoutDisposable = new MultipleAssignmentDisposable();
Action flushBuffer = () =>
{
TSource[] values;
lock (buffer.SyncRoot)
{
values = buffer.ToArray();
buffer.Clear();
}
if (values.Length > 0)
{
o.OnNext(values);
}
};
var sourceSubscription = source.Subscribe(
value =>
{
buffer.Add(value);
timeoutDisposable.Disposable = scheduler.Schedule(timeout, flushBuffer);
},
o.OnError,
() =>
{
flushBuffer();
o.OnCompleted();
});
return new CompositeDisposable(sourceSubscription, timeoutDisposable);
});
}
@pombredanne
Copy link

pombredanne commented Jun 14, 2023

Hey! thanks for this! what is your license for it?

@putridparrot
Copy link
Author

putridparrot commented Jun 14, 2023

Honestly I never even thought about licences to gist, but I suppose I should. So let's simply say it's MIT. I'll maybe have to sort out how I display such licensing for Gists.

Update: Okay I've added a basic license text - thanks for pointing this out to me.

@pombredanne
Copy link

Thank you ++

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment