using Млаумчерб.Клиент.зримое; using Timer = DTLib.Timer; namespace Млаумчерб.Клиент.сеть; public record struct DownloadProgress(DataSize Downloaded, DataSize Total, DataSize PerSecond) { public override string ToString() { return $"{Downloaded}/{Total} ({PerSecond}/s)"; } } public class NetworkProgressReporter : IDisposable { private readonly Action _reportProgressDelegate; private long _totalSize; private long _curSize; private long _prevSize; private int _timerDelay = 1000; private Timer _timer; public NetworkProgressReporter(long totalSize, Action reportProgressDelegate) { _totalSize = totalSize; _reportProgressDelegate = reportProgressDelegate; _timer = new Timer(true, _timerDelay, ReportProgress); } // atomic add public void AddBytesCount(byte[] buffer, int offset, int count) { Interlocked.Add(ref _curSize, count); } public void Start() { _timer.Start(); } public void Stop() { _timer.Stop(); _timer.InvokeAction(); } public void Dispose() { Stop(); } void ReportProgress() { long bytesPerSec = (_curSize - _prevSize) / (_timerDelay / 1000); _prevSize = _curSize; var p = new DownloadProgress(_curSize, _totalSize, bytesPerSec); Приложение.Логгер.LogDebug(nameof(ReportProgress), $"download progress {p}"); _reportProgressDelegate(p); } }