Индикатор прогресса должен отображать прогресс в реальном времени.C#

Место общения программистов C#
Ответить
Anonymous
 Индикатор прогресса должен отображать прогресс в реальном времени.

Сообщение Anonymous »

Сейчас работаю с MAUI и темой загрузки файла/папки через API. Загрузка работает, но я хотел бы отображать ход загрузки на индикаторе выполнения.
В настоящее время это работает только в том случае, если файл уже полностью загружен, хотя я хотел бы иметь возможность просматривать прогресс в реальном времени.
Вот три фрагмента кода.
Один из 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);
}
И, наконец, из моего пользовательского интерфейса: Попытки работы с Action уже предпринимались. Функция действительно доступна, но только в том случае, если загрузка завершена, как описано.
Я также пробовал:

Код: Выделить всё

while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
чтобы указать текущий статус выполнения или действия. Но так как и это не работает, я в некоторой растерянности

Подробнее здесь: https://stackoverflow.com/questions/786 ... gress-live
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»