В настоящее время это работает только в том случае, если файл уже полностью загружен, хотя я хотел бы иметь возможность просматривать прогресс в реальном времени.
Вот три фрагмента кода.
Один из ViewModel:
Код: Выделить всё
public class DownloadQueueViewModel : INotifyPropertyChanged
{
public ICommand AddDownloadCommand => new Command(AddDownloadToQueue);
private Queue _downloadQueueModels = new Queue();
private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private IApiClient _client;
public ObservableCollection Downloads { get; set; } = new ObservableCollection();
public DownloadQueueViewModel()
{
Task.Run(async () =>
{
AddDownloadToQueue();
});
}
public void AddDownloadToQueue()
{
Task.Run(async () =>
{
while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
var downloadQueue = new DownloadQueueModel { FileName = "fileName" };
_downloadQueueModels.Enqueue(downloadQueue);
Downloads.Add(downloadQueue);
await ProcessQueueAsync(downloadQueue);
await Task.Delay(1000);
}
}, _cancellationTokenSource.Token);
}
private async Task ProcessQueueAsync(DownloadQueueModel downloadQueue)
{
while (_downloadQueueModels.Count > 0)
{
downloadQueue = _downloadQueueModels.Dequeue();
_client = new APIClient();
var statusAction = new Action(status =>
{
downloadQueue.StatusDownload = status;
});
var progress = new Progress(totalRead =>
{
downloadQueue.TotalBytes = totalRead;
if (downloadQueue.FileSize > 0)
{
downloadQueue.Progress = (double)totalRead / downloadQueue.FileSize * 100;
}
});
string filePath = Path.Combine(Path.GetTempPath(), downloadQueue.FileName);
try
{
downloadQueue.StatusDownload = StatusDownload.Downloading;
var fileInfo = await _client.DownloadFileAsync("https://github.com/pterodactyl/panel/files/10056889/egg-file-download-error-test.zip",
statusAction,
filePath,
progress);
downloadQueue.FileName = fileInfo.FullName;
}
catch (Exception ex)
{
downloadQueue.StatusDownload = StatusDownload.Failed;
}
}
}
Код: Выделить всё
public async Task DownloadFileAsync(string url, Action statusDownload, string filePath, IProgress progress)
{
using (var response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
statusDownload(StatusDownload.Running);
var totalBytes = response.Content.Headers.ContentLength;
using (var stream = await response.Content.ReadAsStreamAsync())
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
statusDownload(StatusDownload.Downloading);
var buffer = new byte[8192];
long totalRead = 0;
int bytesRead;
while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalRead += bytesRead;
if (totalBytes.HasValue)
{
long percentage = totalRead * 100 / totalBytes.Value;
progress?.Report(percentage);
}
}
statusDownload(StatusDownload.Ready);
}
}
return new FileInfo(filePath);
}
Код: Выделить всё
Я также пробовал:
Код: Выделить всё
while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
Подробнее здесь: https://stackoverflow.com/questions/786 ... gress-live
Мобильная версия