namespace Млаумчерб.Клиент.сеть; public class NetworkTask : IDisposable { public readonly string Name; public enum Status { Initialized, Started, Completed, Cancelled, Failed }; public Status DownloadStatus { get; private set; } = Status.Initialized; public event Action? OnStart; public event Action? OnProgress; public event Action? OnStop; public delegate Task DownloadAction(NetworkProgressReporter progressReporter, CancellationToken ct); private readonly DownloadAction _downloadAction; private CancellationTokenSource _cts = new(); private NetworkProgressReporter _progressReporter; public NetworkTask(string name, long dataSize, DownloadAction downloadAction) { Name = name; _downloadAction = downloadAction; _progressReporter = new NetworkProgressReporter(dataSize, ReportProgress); } private void ReportProgress(DownloadProgress p) => OnProgress?.Invoke(p); public async Task StartAsync() { if(DownloadStatus == Status.Started || DownloadStatus == Status.Completed) return; DownloadStatus = Status.Started; try { _progressReporter.Start(); OnStart?.Invoke(); await _downloadAction(_progressReporter, _cts.Token); DownloadStatus = Status.Completed; } catch (OperationCanceledException) { DownloadStatus = Status.Cancelled; } catch { DownloadStatus = Status.Failed; throw; } finally { _progressReporter.Stop(); OnStop?.Invoke(DownloadStatus); } } public void Cancel() { DownloadStatus = Status.Cancelled; _cts.Cancel(); _cts = new CancellationTokenSource(); } public void Dispose() { _cts.Dispose(); _progressReporter.Dispose(); } }