添加失败文件重试机制

This commit is contained in:
zzz
2025-06-18 20:41:17 +08:00
parent 369be0032e
commit 286589cddb
2 changed files with 119 additions and 2 deletions

117
Form1.cs
View File

@@ -257,6 +257,7 @@ namespace CheckDownload
_downloadedFiles.Clear();
var options = new ParallelOptions { MaxDegreeOfParallelism = 4 };
var failedFiles = new Dictionary<string, string>(); // 记录下载失败的文件
await Task.Run(() =>
{
@@ -316,15 +317,32 @@ namespace CheckDownload
else
{
UpdateStatus($"备用方案已执行");
// 记录失败的文件,稍后重试
lock (failedFiles)
{
failedFiles[filePath] = expectedMd5;
}
}
}
catch (Exception ex)
{
UpdateStatus($"下载文件 {filePath} 失败: {ex.Message}");
// 记录失败的文件,稍后重试
lock (failedFiles)
{
failedFiles[filePath] = expectedMd5;
}
}
});
});
// 如果有失败的文件,进行重试
if (failedFiles.Count > 0)
{
UpdateStatus($"开始重试 {failedFiles.Count} 个失败的文件...");
await RetryFailedFiles(failedFiles);
}
if (_downloadedFiles.Count != fileList.Count)
{
throw new Exception($"部分文件下载失败,成功 {_downloadedFiles.Count}/{fileList.Count}");
@@ -339,6 +357,105 @@ namespace CheckDownload
}
}
/// <summary>
/// 重试下载失败的文件
/// </summary>
/// <param name="failedFiles">失败的文件字典</param>
private async Task RetryFailedFiles(Dictionary<string, string> failedFiles)
{
const int maxRetries = 2; // 最大重试次数
var retryFiles = new Dictionary<string, string>(failedFiles);
for (int retryCount = 1; retryCount <= maxRetries; retryCount++)
{
if (retryFiles.Count == 0) break;
UpdateStatus($"第 {retryCount} 次重试,剩余 {retryFiles.Count} 个文件...");
var currentRetryFiles = new Dictionary<string, string>(retryFiles);
retryFiles.Clear();
foreach (var file in currentRetryFiles)
{
string filePath = file.Key;
string expectedMd5 = file.Value;
try
{
UpdateStatus($"重试下载: {filePath}");
// 先尝试主下载
bool success = false;
try
{
OssClient client = new OssClient(OssEndpoint, OssAccessKeyId, OssAccessKeySecret);
string ossKey = $"File/{expectedMd5}";
var obj = client.GetObject(OssBucketName, ossKey);
string tempFilePath = Path.Combine(_tempDirectory, filePath);
string tempDir = Path.GetDirectoryName(tempFilePath);
if (!Directory.Exists(tempDir))
{
Directory.CreateDirectory(tempDir);
}
using (var fileStream = File.Create(tempFilePath))
{
obj.Content.CopyTo(fileStream);
}
success = true;
}
catch (Exception ex) when (ex is OssException || ex is WebException)
{
// 主下载失败,尝试备用方案
string ossKey = $"File/{expectedMd5}";
string tempFilePath = Path.Combine(_tempDirectory, filePath);
success = DownloadWithFallback(ossKey, tempFilePath);
}
if (success)
{
lock (_downloadedFiles)
{
_downloadedFiles[filePath] = (null, expectedMd5);
}
Interlocked.Increment(ref _completedCount);
int progress = (int)((double)_completedCount / _totalCount * 95);
UpdateProgressValue(progress);
UpdateStatus($"重试成功: {filePath}");
}
else
{
retryFiles[filePath] = expectedMd5;
UpdateStatus($"重试失败: {filePath}");
}
}
catch (Exception ex)
{
retryFiles[filePath] = expectedMd5;
UpdateStatus($"重试异常: {filePath} - {ex.Message}");
}
// 重试间隔,避免过于频繁
await Task.Delay(1000);
}
if (retryFiles.Count > 0 && retryCount < maxRetries)
{
UpdateStatus($"等待 3 秒后进行第 {retryCount + 1} 次重试...");
await Task.Delay(3000);
}
}
if (retryFiles.Count > 0)
{
UpdateStatus($"重试完成,仍有 {retryFiles.Count} 个文件下载失败");
}
else
{
UpdateStatus("所有文件重试成功!");
}
}
private async Task<List<string>> GetIpAddressesForDomain(string domain)
{
try