使用 Parallel.for 循环的文件 I/O 问题

本文关键字:问题 文件 Parallel for 循环 使用 | 更新日期: 2023-09-27 18:32:15

我有一个控制台应用程序,计划处理大量平面文件。为了提高性能,我提供了使用并行处理的选项。它大大提高了性能。但是,当某些迭代正在复制和删除文件时,它现在会导致奇怪的错误。我不知道为什么会发生这种情况或如何解决它。我不明白为什么迭代分配到的线程会因为每个文件和关联的 id 不同而发生冲突。这是我的基本代码和错误:

static void Main(string[] args)
    {
        Parallel.For(0, fileCount, i =>
                        {
                            dxmtId = Convert.ToInt32(dxmtIds[i]);
                            iflId = Convert.ToInt32(iflIds[i]);
                            islId = Convert.ToInt32(islIds[i]);
                            fileName = fileNames[i].ToString();
                            LoadFileIntoDatabase(monitorId, islId, dxmtId, iflId, fileName);
                        });
    }
    private static void LoadFileIntoDatabase (int procId, int islId, int dxmtId, iflId, fileName )
    {
        string fileNameDone = fileName + ".done";
        if (File.Exists(fileName))
        {
             // code for successfully loading file 
             myCommand = @"CMD.EXE";
             ProcessStartInfo startInfo = new ProcessStartInfo(myCommand)
                    {
                        WorkingDirectory = ConfigurationManager.AppSettings["ExportPath"].ToString(),
                        Arguments = @"/c SQLLDR CONTROL=" + controlFileWithPath + " PARFILE=" + parFileWithPath,
                        //RedirectStandardOutput = true,
                        RedirectStandardError = true,
                        UseShellExecute = false,
                        CreateNoWindow = true
                    };
            Process process = new Process();
            process.StartInfo = startInfo;
            process.Start();
            process.WaitForExit();
            exitCode = process.ExitCode;
            try 
            {
                File.Copy(fileName, fileNameDone, true); //rename file to .done
                File.Delete(fileName); //delete original file
            }
            catch (exception ex)
            {
                File.AppendAllText(@"c:'temp'fileerrors.txt", ex.Message + " " + " on copying or deleting file name: " + fileName +  Environment.NewLine);
            }
        }
    }

错误为 1)"找不到文件..."或 2) "进程无法访问文件...'"

关于如何修复/诊断正在发生的事情的任何建议?

使用 Parallel.for 循环的文件 I/O 问题

我认为问题很可能是File.Copy()的过程仍然对原始文件有句柄,因此File.Delete()失败。

我建议您改用File.Move(),因为这实际上资源密集度较低。在内部,File.Move()使用 Win32Native.MoveFile 函数,该功能在文件系统上执行重命名。如果使用 File.Copy() ,则实际上将复制磁盘上的数据,这将更加耗费资源且速度更慢。但是,如果需要保留数据的两个副本(在您的示例中似乎并非如此),则应避免File.Move()

所需的代码更改将如下所示:

try
{
    File.Move(fileName, fileNameDone);
}

您可能还希望更仔细地查看catch块并更可靠地定位已知错误,即

catch (IOException ex)
{
    // specific error type expected
}

希望这能让你更进一步。