Имеется .NET 7 (WPF) приложение, в котором пользователь может скачивать некоторые файлы. Мой план заключается в том, чтобы сначала собрать задачи скачивания в список (чанк) и уже потом сразу весь чанк задач выполнить. Но, видимо, я упускаю что-то очень важное, ибо скачивание файла начинается сразу же после создания задачи.
Метод скачивания, пробовал и цепочку и async/await:
public Task DownloadAsync(PostModel post, string saveDirectory, CancellationToken cancellationToken)
{
var filePath = Path.Combine(saveDirectory, $"{post.Id}{Path.GetExtension(post.FileUrl)}");
if (!File.Exists(filePath))
{
return _httpClient.GetAsync(post.FileUrl, cancellationToken)
.ContinueWith(x => x.Result.Content.ReadAsByteArrayAsync(cancellationToken)
.ContinueWith(y => File.WriteAllBytesAsync(filePath, y.Result, cancellationToken), cancellationToken), cancellationToken);
//using var response = await _httpClient.GetAsync(post.FileUrl, cancellationToken);
//var responseByteArray = await response.Content.ReadAsByteArrayAsync(cancellationToken);
//await File.WriteAllBytesAsync(filePath, responseByteArray, cancellationToken);
}
return Task.FromResult(0);
}
Цикл, где используются скачивание (упростил для размещения):
var chunkDownloadTasks = new List<Task>();
foreach (var post in posts.Posts)
{
var downloadTask = (GetContentTypeFromUrl(post.FileUrl) switch
{
ContentType.Image when settings.IncludeImages => _downloadService.DownloadAsync(post, GetFolder(settings.SavePath, ref imagesFolder, "Images"), cancellationToken),
ContentType.Video when settings.IncludeVideo => _downloadService.DownloadAsync(post, GetFolder(settings.SavePath, ref videoFolder, "Video"), cancellationToken),
ContentType.Gif when settings.IncludeGifs => _downloadService.DownloadAsync(post, GetFolder(settings.SavePath, ref gifFolder, "Gif"), cancellationToken),
_ => null
})?.ContinueWith(_ =>
{
status.Downloaded++;
progress.Report(status);
}, cancellationToken);
if (downloadTask == null)
{
status.Skipped++;
progress.Report(status);
continue;
}
chunkDownloadTasks.Add(downloadTask);
if (chunkDownloadTasks.Count == ChunkSize)
{
await Task.WhenAll(chunkDownloadTasks.ToArray());
chunkDownloadTasks.Clear();
}
}
ContinueWithотработает уже послеWhenAllи выхода из функции? Да, вероятность этого мала и ещё меньше вероятность того, что локальная коллекцияtasksуспеет утилизироваться. Но такая вероятность, мне кажется, есть и в результате будет что-то нехорошее. – CrazyElf Oct 14 '23 at 10:49а суть проблемы то в чем, медленно качается, или что? - Так это и не суть, но чанками качать маленькие файлы быстрее. > Метод скачивания почему-то у вас всасывает все данные в память, зачем? - Знаю, это пока что playground, просто играюсь с разными вещами. Я не эксперт, чтобы сразу идеальный код выдать, решаю проблемы по одной. Но спасибо за ваш ответ, буду изучать
– Jagailo Oct 14 '23 at 15:37