72 lines
2.1 KiB
C#
72 lines
2.1 KiB
C#
using System.Net.Http;
|
||
using System.Runtime.CompilerServices;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace Млаумчерб.Клиент;
|
||
|
||
public record struct NetworkTransferResult(long BytesTotal, long BytesTransferred, long BytesPerSecond)
|
||
{
|
||
public override string ToString()
|
||
{
|
||
return $"transferred {BytesTransferred}/{BytesTotal} bytes ({BytesPerSecond}) bps";
|
||
}
|
||
}
|
||
|
||
public class NetworkTransferTask
|
||
{
|
||
public Task Task { get; private set; }
|
||
public Progress<NetworkTransferResult> Progress { get; private set; }
|
||
|
||
private Stream _src;
|
||
private Stream _dst;
|
||
private CancellationTokenSource _cts;
|
||
private DTLib.Timer _timer;
|
||
|
||
public NetworkTransferTask(Stream src, Stream dst)
|
||
{
|
||
_src = src;
|
||
_dst = dst;
|
||
_cts = new CancellationTokenSource();
|
||
Progress = new Progress<NetworkTransferResult>();
|
||
_timer = new(true, 1000, ReportProgress);
|
||
Task = Task.CompletedTask;
|
||
}
|
||
|
||
public void Start()
|
||
{
|
||
_timer.Start();
|
||
Task = _src.CopyToAsync(_dst);
|
||
_timer.Stop();
|
||
}
|
||
|
||
public void Stop()
|
||
{
|
||
_cts.Cancel();
|
||
_timer.Stop();
|
||
}
|
||
|
||
private long previousBytesTransferred;
|
||
private void ReportProgress()
|
||
{
|
||
long bytesTotal = _src.Length, bytesTransferred = _src.Position;
|
||
long bytesPerSecond = bytesTransferred - previousBytesTransferred;
|
||
previousBytesTransferred = bytesTransferred;
|
||
((IProgress<NetworkTransferResult>)Progress).Report(new NetworkTransferResult(bytesTotal, bytesTransferred, bytesPerSecond));
|
||
}
|
||
|
||
public TaskAwaiter GetAwaiter() => Task.GetAwaiter();
|
||
}
|
||
|
||
public static class NetworkHelper
|
||
{
|
||
private static HttpClient http = new();
|
||
|
||
public static NetworkTransferTask DownloadHTTPFileAsync(string url, Stream destinationStream)
|
||
{
|
||
var sourceStream = http.GetStreamAsync(url).GetAwaiter().GetResult();
|
||
NetworkTransferTask task = new(sourceStream, destinationStream);
|
||
task.Start();
|
||
return task;
|
||
}
|
||
} |