直接上代码:
//最大线程下载数量
ParallelOptions options = new ParallelOptions
{
MaxDegreeOfParallelism = 5
};
public async Task DownloadMusicUrl(List<MusicTags> musicTags)
{
DateTime currentTime = DateTime.Now;
DateTime startTime = new DateTime(1970, 1, 1);
TimeSpan timeSpan = currentTime - startTime;
string timestamp = ((long)timeSpan.TotalMilliseconds).ToString();
string type = string.Empty;
if (this.mp3.Checked) type = this.mp3.Text;
if (this.flac.Checked) type = this.flac.Text;
if (this.mv.Checked) type = this.mv.Text;
并行下载URL列表中的所有文件
List<Task> downloadTasks = new List<Task>();
Parallel.ForEach(musicTags, options, tag =>
{
Task task = Download(tag, timestamp, type);
downloadTasks.Add(task); // 将下载任务的 Task 添加到 downloadTasks 列表中
await Task.Delay(500);
});
await Task.WhenAll(downloadTasks C#有偿Q群:927860652); // 等待所有下载任务完成
}
这里切记先用 Task task = Download(tag, timestamp, type);
把任务添加到集合,不要直接await
在ForEach的委托里面执行代码,这样会出现一些无法控制的bug,任务添加完成后,在最外面await Task.WhenAll(downloadTasks);
通过这个等待下载完成。
这样就可以很好的控制并行下载呢。
public async Task Download(MusicTags tag, string timestamp, string type = "mp3")
{
using (WebClient webClient = new WebClient())
{
try
{
string solutionPath = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory))));
string folderPath = Path.Combine(solutionPath, "资源下载", DateTime.Now.ToString("yyyyMMdd"), timestamp);
gloFolderPath = folderPath;
Directory.CreateDirectory(folderPath);
string name = $"{tag.baseMusic.SongTitle}-{tag.baseMusic.Singer}.{type}";
// 设置下载完成后保存的本地路径和文件名
string localPath = Path.Combine(folderPath, name); // 替换为保存路径
// 订阅 DownloadProgressChanged 事件来更新进度条
webClient.DownloadProgressChanged += (s, args) =>
{
int progress = args.ProgressPercentage;
long bytesReceived = args.BytesReceived;
long totalBytesToReceive = args.TotalBytesToReceive;
UpdateProgressBar(progress, bytesReceived, totalBytesToReceive, name);
};
await webClient.DownloadFileTaskAsync(new Uri(tag.tag), localPath);
//Console.WriteLine("音乐下载完成,保存路径:" + localPath);
}
catch (Exception ex)
{
Console.WriteLine("音乐下载失败:" + ex.Message + ex.StackTrace);
}
}
// 下载完成后,更新进度条为 100%
UpdateProgressBar(100, 0, 0, "下载完成");
AppendLog($"{tag.baseMusic.SongTitle}-{tag.baseMusic.Singer} 已下载");
}