From d2906476c87ed69c90a3e69496c2faecf940da40 Mon Sep 17 00:00:00 2001 From: CJK_mkp <113243675+CJKmkp@users.noreply.github.com> Date: Sun, 2 Nov 2025 10:46:16 +0800 Subject: [PATCH] =?UTF-8?q?add:Dlass=E8=81=94=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Helpers/DlassNoteUploader.cs | 125 +++++++++++++++++++++--- 1 file changed, 112 insertions(+), 13 deletions(-) diff --git a/Ink Canvas/Helpers/DlassNoteUploader.cs b/Ink Canvas/Helpers/DlassNoteUploader.cs index 0d67e3a2..4265c2bc 100644 --- a/Ink Canvas/Helpers/DlassNoteUploader.cs +++ b/Ink Canvas/Helpers/DlassNoteUploader.cs @@ -18,11 +18,21 @@ namespace Ink_Canvas.Helpers private const string APP_ID = "app_WkjocWqsrVY7T6zQV2CfiA"; private const string APP_SECRET = "o7dx5b5ASGUMcM72PCpmRQYAhSijqaOVHoGyBK0IxbA"; private const int BATCH_SIZE = 10; // 批量上传大小 + private const int MAX_RETRY_COUNT = 3; // 最大重试次数 /// - /// 上传队列(线程安全) + /// 上传队列项 /// - private static readonly ConcurrentQueue _uploadQueue = new ConcurrentQueue(); + private class UploadQueueItem + { + public string FilePath { get; set; } + public int RetryCount { get; set; } + } + + /// + /// 上传队列 + /// + private static readonly ConcurrentQueue _uploadQueue = new ConcurrentQueue(); /// /// 队列处理锁,防止并发处理 @@ -153,9 +163,13 @@ namespace Ink_Canvas.Helpers /// /// 将文件加入上传队列 /// - private static void EnqueueFile(string filePath) + private static void EnqueueFile(string filePath, int retryCount = 0) { - _uploadQueue.Enqueue(filePath); + _uploadQueue.Enqueue(new UploadQueueItem + { + FilePath = filePath, + RetryCount = retryCount + }); // 如果队列达到批量大小,触发批量上传 if (_uploadQueue.Count >= BATCH_SIZE) @@ -177,15 +191,15 @@ namespace Ink_Canvas.Helpers try { - var filesToUpload = new List(); + var filesToUpload = new List(); // 从队列中取出最多BATCH_SIZE个文件 - while (filesToUpload.Count < BATCH_SIZE && _uploadQueue.TryDequeue(out string filePath)) + while (filesToUpload.Count < BATCH_SIZE && _uploadQueue.TryDequeue(out UploadQueueItem item)) { - // 再次检查文件是否存在(可能在队列中时被删除) - if (File.Exists(filePath)) + // 再次检查文件是否存在 + if (File.Exists(item.FilePath)) { - filesToUpload.Add(filePath); + filesToUpload.Add(item); } } @@ -251,11 +265,59 @@ namespace Ink_Canvas.Helpers return; } - // 并发上传所有文件(共享白板信息) - var uploadTasks = filesToUpload.Select(filePath => UploadFileInternalAsync(filePath, sharedWhiteboard, apiBaseUrl, userToken)); + // 并发上传所有文件(共享白板信息),并处理失败重试 + var uploadTasks = filesToUpload.Select(async item => + { + try + { + var success = await UploadFileInternalAsync(item.FilePath, sharedWhiteboard, apiBaseUrl, userToken); + if (!success) + { + // 检查是否是可重试的错误 + if (IsRetryableError(item.FilePath)) + { + // 检查重试次数 + if (item.RetryCount < MAX_RETRY_COUNT) + { + LogHelper.WriteLogToFile($"上传失败,将重试 ({item.RetryCount + 1}/{MAX_RETRY_COUNT}): {Path.GetFileName(item.FilePath)}", LogHelper.LogType.Event); + EnqueueFile(item.FilePath, item.RetryCount + 1); + } + else + { + LogHelper.WriteLogToFile($"上传失败,已达到最大重试次数: {Path.GetFileName(item.FilePath)}", LogHelper.LogType.Error); + } + } + } + return success; + } + catch (Exception ex) + { + // 检查是否是可重试的错误(超时、网络错误等) + var errorMessage = ex.Message.ToLower(); + bool isRetryable = errorMessage.Contains("超时") || + errorMessage.Contains("timeout") || + errorMessage.Contains("网络错误") || + errorMessage.Contains("network"); + + if (isRetryable && IsRetryableError(item.FilePath)) + { + // 检查重试次数 + if (item.RetryCount < MAX_RETRY_COUNT) + { + LogHelper.WriteLogToFile($"上传失败({ex.Message}),将重试 ({item.RetryCount + 1}/{MAX_RETRY_COUNT}): {Path.GetFileName(item.FilePath)}", LogHelper.LogType.Event); + EnqueueFile(item.FilePath, item.RetryCount + 1); + } + else + { + LogHelper.WriteLogToFile($"上传失败,已达到最大重试次数: {Path.GetFileName(item.FilePath)}", LogHelper.LogType.Error); + } + } + return false; + } + }); await Task.WhenAll(uploadTasks); - // 如果队列中还有文件,继续处理 + // 如果队列达到批量大小,继续处理 if (_uploadQueue.Count >= BATCH_SIZE) { _ = ProcessUploadQueueAsync(); @@ -385,10 +447,47 @@ namespace Ink_Canvas.Helpers } catch (Exception ex) { + // 记录错误信息,抛出异常以便调用方判断是否可重试 LogHelper.WriteLogToFile($"上传笔记时出错: {ex.Message}", LogHelper.LogType.Error); - return false; + throw; } } + + /// + /// 判断错误是否可重试(超时、网络错误等) + /// + private static bool IsRetryableError(string filePath) + { + // 检查文件是否存在 + if (!File.Exists(filePath)) + { + return false; // 文件不存在,不可重试 + } + + // 检查文件扩展名 + var fileExtension = Path.GetExtension(filePath).ToLower(); + if (fileExtension != ".png" && fileExtension != ".icstk") + { + return false; // 文件格式错误,不可重试 + } + + // 检查文件大小 + try + { + var fileInfo = new FileInfo(filePath); + if (fileInfo.Length > 10 * 1024 * 1024) + { + return false; // 文件过大,不可重试 + } + } + catch + { + return false; // 无法读取文件信息,不可重试 + } + + // 其他错误(超时、网络错误等)可以重试 + return true; + } } }