多任务并行处理用户时如何实时获取各任务进度并汇总
解决方案
首先,我们需要定义存储用户处理结果的类,利用IProgress<T>实现进度上报,并通过返回带结果的Task收集最终处理状态。
步骤1:定义处理结果类
创建类保存每个用户的处理状态:
public class UserProcessingResult { public string Username { get; set; } public bool IsSuccess { get; set; } // 可选:添加错误信息字段记录失败原因 public string ErrorMessage { get; set; } }
步骤2:修改ProcessUsers方法
更新方法以支持进度上报并返回处理结果:
private async Task<List<UserProcessingResult>> ProcessUsers(List<User> usersList, IProgress<int> progress) { var results = new List<UserProcessingResult>(); foreach (var user in usersList) { var result = new UserProcessingResult { Username = user.Username }; try { // 执行用户处理逻辑:调用外部API、写入数据库等 // 示例:await CallExternalApi(user); // await WriteToDatabase(user); result.IsSuccess = true; } catch (Exception ex) { result.IsSuccess = false; result.ErrorMessage = ex.Message; // 可选:记录异常日志 } finally { results.Add(result); progress.Report(1); // 上报已处理1个用户 } } return results; }
步骤3:更新调用方法CallingMethod
修改调用方法接收进度更新并收集所有处理结果:
private async Task CallingMethod() { int totalProcessed = 0; // 创建进度处理器,线程安全累加已处理用户数 var progressHandler = new Progress<int>(count => { Interlocked.Add(ref totalProcessed, count); // 此处可输出日志或更新UI进度 Console.WriteLine($"整体处理进度:已完成 {totalProcessed}/2000 个用户"); }); // 启动所有分块处理任务 var allTasks = new List<Task<List<UserProcessingResult>>> { ProcessUsers(usersList1, progressHandler), ProcessUsers(usersList2, progressHandler), ProcessUsers(usersList3, progressHandler) // 添加其他分块任务... }; // 等待所有任务完成并获取结果 var allResults = await Task.WhenAll(allTasks); // 合并所有任务的处理结果 var combinedResults = allResults.SelectMany(taskResults => taskResults).ToList(); // 统计成功/失败数量 int successCount = combinedResults.Count(r => r.IsSuccess); int failureCount = combinedResults.Count(r => !r.IsSuccess); Console.WriteLine($"处理完成:成功 {successCount} 个,失败 {failureCount} 个"); // 可进一步处理combinedResults,比如写入日志或生成报表 }
关键说明
- 进度上报:通过
IProgress<T>和Progress<T>实现跨线程进度通知,Interlocked.Add确保多任务环境下的线程安全计数。 - 结果收集:每个
ProcessUsers任务返回用户处理状态列表,利用Task.WhenAll一次性获取所有任务结果后合并。 - 异常处理:在循环内捕获单个用户处理的异常,避免因单个用户失败导致整个任务终止,同时保留失败原因。
内容的提问来源于stack exchange,提问作者Sai Kiran
相关产品推荐
相关产品推荐

