Skip to content

Instantly share code, notes, and snippets.

@smatsson
Created January 23, 2020 15:38
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 smatsson/1e9f348638cbbf9efdfe8ab0c781532b to your computer and use it in GitHub Desktop.
Save smatsson/1e9f348638cbbf9efdfe8ab0c781532b to your computer and use it in GitHub Desktop.
ThrottledStream2
// source: https://stackoverflow.com/a/42133563
public class ThrottledStream2 : Stream
{
private readonly Stream parent;
private readonly int maxBytesPerSecond;
private readonly Stopwatch stopwatch;
private long processed;
public ThrottledStream2(Stream parent, int maxBytesPerSecond)
{
this.maxBytesPerSecond = maxBytesPerSecond;
this.parent = parent;
stopwatch = Stopwatch.StartNew();
processed = 0;
}
protected async Task Throttle(int bytes)
{
processed += bytes;
var targetTime = TimeSpan.FromSeconds((double)processed / maxBytesPerSecond);
var actualTime = stopwatch.Elapsed;
var sleep = targetTime - actualTime;
if (sleep > TimeSpan.Zero)
{
await Task.Delay(sleep).ConfigureAwait(false);
}
}
public override bool CanRead => parent.CanRead;
public override bool CanSeek => parent.CanSeek;
public override bool CanWrite => parent.CanWrite;
public override void Flush() => parent.Flush();
public override long Length => parent.Length;
public override long Position
{
get => parent.Position;
set => parent.Position = value;
}
public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
var numberOfBytesRead = await parent.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
await Throttle(numberOfBytesRead).ConfigureAwait(false);
return numberOfBytesRead;
}
public override int Read(byte[] buffer, int offset, int count) => throw new NotSupportedException();
public override long Seek(long offset, SeekOrigin origin) => parent.Seek(offset, origin);
public override void SetLength(long value) => parent.SetLength(value);
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment