每个不一致的结果并行

时间:2018-04-02 19:51:04

标签: c# parallel-processing task-parallel-library parallel.foreach

我确保在并行循环中有并发收集。我期待在循环结束时有35个唯一的文件路径。我看到重复文件路径的结果不一致。我在这里缺少什么?

ConcurrentBag<string> generatedPdfFilePaths = new 
    ConcurrentBag<string>();                   
string generatedPdfPath = string.Empty;   
Parallel.ForEach(docxPaths, (docxpath) =>                    
{
    generatedPdfPath = docxpath.Replace(".docx", ".pdf");
    if (ConvertDocxToPdf(docxpath, generatedPdfPath))
    { 
        generatedPdfFilePaths.Add(generatedPdfPath); 
    }                    
});

// do stuff with generatedPdfFilePaths collection here
public bool ConvertDocxToPdf(string docxFilePath, string pdfFilePath)
{               
    try
    {
        Aspose.Words.Document docx = new
            Aspose.Words.Document(docxFilePath);
        docx.FontSettings = fontsetting;
        docx.Save(pdfFilePath);                   
        return true;
    }
    catch (Exception ex)
    {
        //do stuff
    }                
}

1 个答案:

答案 0 :(得分:2)

generatedPdfPath变量必须在并行循环内。否则,所有线程(并行循环)都可以访问它。在内部循环中,每个线程都会对其进行修改,并且当线程尝试使用它时,可能&#39; generatedPdfPath值由另一个线程更改。这种情况导致竞争状况。因此,每次执行都会产生不同的结果。

如果将此行string generatedPdfPath = string.Empty;移动到循环中,则必须解决问题。

ConcurrentBag<string> generatedPdfFilePaths = new ConcurrentBag<string>();                   

Parallel.ForEach(docxPaths, (docxpath) =>                    
{
    string generatedPdfPath = string.Empty;   
    generatedPdfPath = docxpath.Replace(".docx", ".pdf");
    if (ConvertDocxToPdf(docxpath, generatedPdfPath))
    { 
        generatedPdfFilePaths.Add(generatedPdfPath); 
    }                    
});