Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When using this library on a Linux system, I am finding wildly inaccurate
BytesPerSecond
values being supplied in theCopyProgress
instances passed into the progress callback functor. Specifically, they seem to be on the order of 100 times larger than the actual transfer speed. I'm not exactly sure what the cause is, but I suspect thatStopwatch
is under-reporting short durations, so that the loop thinks each buffer fill it sends takes less time than it does and is thus much faster than it really is.This PR updates the code to use an average over a window of recent samples instead of trying to capture the time of each individual write operation. It adds a class
SpeedCalculator
which manages a buffer of samples. The loops then supply a new sample each time a write operation completes.SpeedCalculator
automatically takes care of timestamping these supplied samples. Later, a methodCalculateBytesPerSecond
uses the difference between the first and last sample in the buffer. As long asDateTime.UtcNow
is not subject to any significant jitter, this should much more accurately capture the overall transfer speed. The buffer is kept trimmed to a specified duration (a constant currently set to 10 seconds).There is also handling for if the caller somehow ends up going backward in the stream and supplying samples with earlier
position
values. The invariant that the samples have monotonically-increasingposition
values is maintained.The two loops that calculate transfer speeds and pass
CopyProgress
instances to a progress callback are updated to useCopyProgress
to compute the speed.The
SpeedCalculator
class is thoroughly commented and defensively programmed.