使用StreamWriter写入Parallel.Foreach中的不同文件

时间:2014-01-23 18:12:12

标签: c# parallel-processing streamwriter

我试图在Parallel.Foreach循环中编写单独的集合以分离csv。当我运行它时,我收到以下错误:

该进程无法访问文件'C:\ temp \ OCRProcess \ 2011 \ 49 \ OCRProcess-2011-49.csv',因为它正由另一个进程使用。

当我查看所有工作进程时,它们正在打开不同的文件,它们都没有使用相同的文件位置。据我所知,每个线程(工作进程)都没有冲突。

public void GenerateCSVFile(List<CSVFile> csvFiles)
    {
        Parallel.ForEach(csvFiles, (csvfile, state, index) =>
            {
                var fileLocation = _storageLocation + csvfile.Type + s + csvfile.Year + s + csvfile.Day + s + csvfile.Type + "-" +
                           csvfile.Year + "-" + csvfile.Day + ".csv";

                if (!File.Exists(fileLocation))
                {
                    File.Create(fileLocation);
                }

                using (var streamWriter = new StreamWriter(fileLocation))
                {
                    foreach (var csvRecord in csvfile.CSVRecords)
                    {
                        streamWriter.WriteLine(csvRecord.Object_Id + "," + csvRecord.DocumentName + "," + csvRecord.BCI_DCN + "," + csvRecord.CreationDate);
                    }
                }                    
            });
    }

以下是CSV文件和CSVRecord类。

public sealed class CSVRecord
{
    public String BCI_DCN { get; set; }
    public String Object_Id { get; set; }
    public String DocumentName { get; set; }
    public String CreationDate { get; set; }
}



public sealed  class CSVFile
{
    public List<CSVRecord> CSVRecords { get; set; }
    public String Year { get; set; }
    public String Type { get; set; }
    public String Day { get; set; }

    public CSVFile()
    {
        CSVRecords = new List<CSVRecord>();
    }
}

1 个答案:

答案 0 :(得分:2)

问题归因于File.Create(fileLocation),它返回FileStream并保持文件打开。当StreamWriter尝试打开它时,它已经打开并导致错误。

要解决此问题,请删除以下IF语句:

if (!File.Exists(fileLocation))
{
    File.Create(fileLocation);
}

并更新了USING声明,如下所示。通过添加TRUE参数,它允许StreamWriter附加到文件(如果存在),否则创建它。

using (var streamWriter = new StreamWriter(fileLocation, true))
{
    foreach (var csvRecord in csvfile.CSVRecords)
    {
        streamWriter.WriteLine(csvRecord.Object_Id + "," + csvRecord.DocumentName + "," + csvRecord.BCI_DCN + "," + csvRecord.CreationDate);
    }
}