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

标签 c# multithreading file-io parallel-processing task-parallel-library

我有一个控制台应用程序,计划处理大量平面文件。为了提高性能,我提供了使用并行处理的选项。它显着提高了性能。但是,当某些迭代复制和删除文件时,它现在会导致奇怪的错误。我不知道为什么会这样或如何解决它。我不明白为什么分配给迭代的线程会发生冲突,因为每个文件和关联的 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)“进程无法访问文件...”

关于如何修复/诊断正在发生的事情有什么建议吗?

最佳答案

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

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

您所需的代码更改看起来有点像这样:

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

您可能还想更仔细地查看 catch block 并更仔细地定位已知错误,即

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

希望这能让你更上一层楼。

关于c# - 使用 Parallel.for 循环的文件 I/O 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35067125/

相关文章:

c# - 区分void和任务返回方法

c++ - openMP 的目标和目标数据之间的区别?

java - Akka future 指导

java - 如何将控制台输出写入 txt 文件

c# - C#中的模糊匹配

c# - 如何正确使用 IReadOnlyDictionary?

c# - DotNetNuke 如何散列其密码?

c# - Unity3d 中的多线程脚本调用

winapi - 如何取消创建文件

c - 如何从文本文件中的制表符分隔字段中正确获取数据