Created
January 23, 2020 15:38
-
-
Save smatsson/1e9f348638cbbf9efdfe8ab0c781532b to your computer and use it in GitHub Desktop.
ThrottledStream2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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