Parallel ForEach结果不一致排查:用ConcurrentBag仍现重复路径
解决Parallel循环中ConcurrentBag出现重复文件路径的问题
我一眼就揪出问题所在了——你在Parallel循环外部声明了generatedPdfPath这个共享变量!在并行执行场景下,多个线程会同时读写这个变量,直接造成了竞态条件:比如线程A刚把路径设为file1.pdf,还没来得及添加到ConcurrentBag里,线程B就把这个变量改成了file2.pdf,结果线程A最终添加的可能是线程B修改后的路径,自然就出现了重复。
ConcurrentBag本身是线程安全的,但你生成路径的环节没做好线程隔离,才导致了这个问题。修复起来很简单,把generatedPdfPath移到循环的委托内部,让每个线程都拥有自己的局部变量,彻底避免线程间的变量干扰。
修复后的代码示例:
ConcurrentBag<string> generatedPdfFilePaths = new ConcurrentBag<string>(); Parallel.ForEach(docxPaths, (docxpath) => { // 将变量移至委托内部,每个线程独立持有 string generatedPdfPath = docxpath.Replace(".docx", ".pdf"); if (ConvertDocxToPdf(docxpath, generatedPdfPath)) { generatedPdfFilePaths.Add(generatedPdfPath); } });
额外提醒一下:还要检查ConvertDocxToPdf方法本身是否线程安全——比如它有没有使用全局共享资源(比如单例的Word应用实例、共享文件流等)。如果是用Office互操作转换文件,通常每个线程需要创建独立的Office实例,避免跨线程操作同一个实例引发异常或文件损坏。
内容的提问来源于stack exchange,提问作者Bala P
相关产品推荐
相关产品推荐

