Skip to content

Commit

Permalink
优化多线程下载稳定性
Browse files Browse the repository at this point in the history
  • Loading branch information
nilaoda committed May 7, 2022
1 parent 4196ce3 commit 8d98192
Showing 1 changed file with 19 additions and 26 deletions.
45 changes: 19 additions & 26 deletions BBDown/BBDownUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ public static async Task<string> GetSSIdByMDAsync(string mdId)
private static async Task RangeDownloadToTmpAsync(int id, string url, string tmpName, long fromPosition, long? toPosition, Action<int, long, long> onProgress, bool failOnRangeNotSupported = false)
{
DateTimeOffset? lastTime = File.Exists(tmpName) ? new FileInfo(tmpName).LastWriteTimeUtc : null;
using (var fileStream = new FileStream(tmpName, FileMode.OpenOrCreate))
using (var fileStream = new FileStream(tmpName, FileMode.Create))
{
fileStream.Seek(0, SeekOrigin.End);
var downloadedBytes = fromPosition + fileStream.Position;
Expand Down Expand Up @@ -321,6 +321,9 @@ private static async Task RangeDownloadToTmpAsync(int id, string url, string tmp
downloadedBytes += recevied;
onProgress(id, downloadedBytes - fromPosition, totalBytes);
}

if (response.Content.Headers.ContentLength != null && (response.Content.Headers.ContentLength != new FileInfo(tmpName).Length))
throw new Exception("Retry...");
}
}

Expand Down Expand Up @@ -359,33 +362,22 @@ public static async Task DownloadFile(string url, string path, bool aria2c, stri
Console.WriteLine();
return;
}
int retry = 0;
string tmpName = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path) + ".tmp");
using (var progress = new ProgressBar())
{
await RangeDownloadToTmpAsync(0, url, tmpName, 0, null, (_, downloaded, total) => progress.Report((double)downloaded / total));
File.Move(tmpName, path, true);
}
}

//https://stackoverflow.com/a/25877042
public static async Task RunWithMaxDegreeOfConcurrency<T>(
int maxDegreeOfConcurrency, IEnumerable<T> collection, Func<T, Task> taskFactory)
{
var activeTasks = new List<Task>(maxDegreeOfConcurrency);
foreach (var task in collection.Select(taskFactory))
reDown:
try
{
activeTasks.Add(task);
if (activeTasks.Count == maxDegreeOfConcurrency)
using (var progress = new ProgressBar())
{
await Task.WhenAny(activeTasks.ToArray());
//observe exceptions here
activeTasks.RemoveAll(t => t.IsCompleted);
await RangeDownloadToTmpAsync(0, url, tmpName, 0, null, (_, downloaded, total) => progress.Report((double)downloaded / total));
File.Move(tmpName, path, true);
}
}
await Task.WhenAll(activeTasks.ToArray()).ContinueWith(t =>
catch (Exception)
{
//observe exceptions in a manner consistent with the above
});
if (++retry == 3) throw;
goto reDown;
}
}

public static async Task MultiThreadDownloadFileAsync(string url, string path, bool aria2c, string aria2cProxy, bool forceHttp = false)
Expand Down Expand Up @@ -417,7 +409,7 @@ public static async Task MultiThreadDownloadFileAsync(string url, string path, b
using (var progress = new ProgressBar())
{
progress.Report(0);
await RunWithMaxDegreeOfConcurrency(8, allClips, async clip =>
await Parallel.ForEachAsync(allClips, async (clip, _) =>
{
int retry = 0;
string tmp = Path.Combine(Path.GetDirectoryName(path), clip.index.ToString("00000") + "_" + Path.GetFileNameWithoutExtension(path) + (Path.GetExtension(path).EndsWith(".mp4") ? ".vclip" : ".aclip"));
Expand All @@ -432,9 +424,10 @@ await RangeDownloadToTmpAsync(clip.index, url, tmp, clip.from, clip.to == -1 ? n
}
catch (NotSupportedException)
{
throw;
if (++retry == 3) throw new Exception($"服务器可能并不支持多线程下载,请使用 --multi-thread false 关闭多线程");
goto reDown;
}
catch
catch (Exception)
{
if (++retry == 3) throw new Exception($"Failed to download clip {clip.index}");
goto reDown;
Expand All @@ -449,7 +442,7 @@ private static List<Clip> GetAllClips(string url, long fileSize)
List<Clip> clips = new List<Clip>();
int index = 0;
long counter = 0;
int perSize = 5 * 1024 * 1024;
int perSize = 10 * 1024 * 1024;
while (fileSize > 0)
{
Clip c = new Clip();
Expand Down

0 comments on commit 8d98192

Please sign in to comment.