使用 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) "进程无法访问文件...'"
关于如何修复/诊断正在发生的事情的任何建议?
我认为问题很可能是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
}
希望这能让你更进一步。