✅ 多线程 + 进度条优化版(生产级)
以下实现结合多线程与精细进度控制,适合超大文件处理:
核心优化思路
- 读取阶段:单线程顺序读取(文件I/O最安全高效)
- 统计阶段:多线程并行处理数据行(
Parallel.ForEach) - 写入阶段:单线程顺序写入(保证顺序正确)
- 进度反馈:使用
IProgress<T>+SynchronizationContext安全更新 UI
完整代码实现
1. 进度报告类
publicclassProgressReport{publicintPercent{get;set;}publicstringStage{get;set;}publicstringDetail{get;set;}publicProgressReport(intpercent,stringstage,stringdetail=""){Percent=percent;Stage=stage;Detail=detail;}}2.异步按钮事件
privateasyncvoidbtnGenerate_Click(objectsender,EventArgse){btnGenerate.Enabled=false;progressBar1.Visible=true;lblProgress.Text="启动处理...";try{stringoutputPath=Path.Combine(Path.GetDirectoryName(txtInputFile.Text),$"Datalog_{txtJobNam.Text}_{txtLotId.Text}_{DateTime.Now:yyyyMMddHHmmssfff}.csv");varprogress=newProgress<ProgressReport>(report=>{progressBar1.Value=Math.Min(report.Percent,100);lblProgress.Text=$"{report.Stage}{report.Percent}% -{report.Detail}";});awaitTask.Run(()=>GenerateCsvMultiThreaded(outputPath,progress));lblProgress.Text="✅ 处理完成!";MessageBox.Show($"生成成功!\n{outputPath}","成功");}catch(Exceptionex){MessageBox.Show($"错误:{ex.Message}","失败",MessageBoxButtons.OK,MessageBoxIcon.Error);}finally{btnGenerate.Enabled=true;}}3.多线程主处理方法
privatevoidGenerateCsvMultiThreaded(stringoutputPath,IProgress<ProgressReport>progress){stringinputPath=txtInputFile.Text;progress?.Report(newProgressReport(0,"初始化"));// ==================== 第一阶段:多线程统计 ====================progress?.Report(newProgressReport(5,"多线程统计数据"));varstats=CalculateStatisticsMultiThread(inputPath,progress);progress?.Report(newProgressReport(45,"正在生成文件头"));// ==================== 第二阶段:写入文件 ====================using(varfs=newFileStream(outputPath,FileMode.Create,FileAccess.Write,FileShare.None,128*1024))using(varwriter=newStreamWriter(fs,Encoding.UTF8)){// 前7行CopyFirstNLines(inputPath,writer,7);progress?.Report(newProgressReport(52,"写入参数区"));WriteHeaderSection(writer,stats);progress?.Report(newProgressReport(58,"写入Bin汇总"));WriteBinSummary(writer,stats);progress?.Report(newProgressReport(65,"复制测试数据"));// 数据区复制(可考虑多线程分段写入,但需小心顺序)CopyDataSectionMultiThread(inputPath,writer,progress);}progress?.Report(newProgressReport(100,"完成"));}4.多线程统计核心(关键优化)
privateStatsCalculateStatisticsMultiThread(stringfilePath,IProgress<ProgressReport>progress){varlines=newList<string>();booldataStarted=false;// 第一步:读取所有数据行(顺序)using(varsr=newStreamReader(filePath)){stringline;while((line=sr.ReadLine())!=null){if(line.StartsWith("STAT_NUM",StringComparison.OrdinalIgnoreCase)){dataStarted=true;continue;}if(dataStarted&&!string.IsNullOrWhiteSpace(line))lines.Add(line);}}progress?.Report(newProgressReport(15,"数据加载完成,开始并行计算"));vardutDict=newDictionary<string,bool>();varbinDict=newDictionary<(stringsoft,stringhard),BinInfo>();// ==================== 多线程并行处理 ====================objectlockObj=newobject();intprocessed=0;inttotalLines=lines.Count;Parallel.ForEach(lines,newParallelOptions{MaxDegreeOfParallelism=Environment.ProcessorCount},line=>{varcells=line.Split(new[]{','},StringSplitOptions.None);if(cells.Length<9)return;stringpartId=cells[2].Trim();stringsoftBin=cells[4].Trim();stringhardBin=cells[5].Trim();stringresult=cells[8].Trim().ToUpperInvariant();lock(lockObj){if(!dutDict.ContainsKey(partId))dutDict[partId]=result=="PASS";elseif(result!="PASS")dutDict[partId]=false;varkey=(softBin,hardBin);if(!binDict.ContainsKey(key))binDict[key]=newBinInfo{SoftBin=softBin,HardBin=hardBin};binDict[key].Count++;if(result!="PASS")binDict[key].IsPass=false;}// 进度更新Interlocked.Increment(refprocessed);if(processed%5000==0){intpercent=15+(int)(30*processed/(double)totalLines);progress?.Report(newProgressReport(percent,"并行统计中",$"{processed}/{totalLines}"));}});// 计算最终统计varstats=newStats{Total=dutDict.Count,Pass=dutDict.Values.Count(v=>v),Fail=dutDict.Values.Count(v=>!v),FTTotal=dutDict.Count,FTPass=dutDict.Values.Count(v=>v),FTFail=dutDict.Values.Count(v=>!v),BinList=binDict.Values.OrderBy(b=>b.SoftBin).ToList()};stats.Yield=stats.Total==0?0:Math.Round(stats.Pass*100.0/stats.Total,2);returnstats;}5. 其他辅助方法(简略)
CopyFirstNLines、WriteHeaderSection、WriteBinSummary、CopyDataSectionMultiThread等可参考之前版本。
多线程优势:
- 统计阶段充分利用多核CPU
- 大幅提升大数据文件处理速度
- 进度反馈依然平滑准确