gpt4 book ai didi

c# - File.Copy in Parallel.ForEach

转载 作者:太空狗 更新时间:2023-10-29 18:04:44 24 4
gpt4 key购买 nike

我正在尝试创建一个目录并在 Parallel.ForEach 中复制一个文件 (pdf)。

下面是一个简单的例子:

    private static void CreateFolderAndCopyFile(int index)
{
const string sourcePdfPath = "c:\\testdata\\test.pdf";
const string rootPath = "c:\\testdata";

string folderDirName = string.Format("Data{0}", string.Format("{0:00000000}", index));

string folderDirPath = rootPath + @"\" + folderDirName;

Directory.CreateDirectory(folderDirPath);

string desPdfPath = folderDirPath + @"\" + "test.pdf";

File.Copy(sourcePdfPath, desPdfPath, true);

}

上面的方法创建了一个新的文件夹,并将pdf文件复制到一个新的文件夹中。它创建了这个目录树:

TESTDATA
-Data00000000
-test.pdf
-Data00000001
-test.pdf
....
-Data0000000N
-test.pdf

我尝试在 Parallel.ForEach 循环中调用 CreateFolderAndCopyFile 方法。

    private static void Func<T>(IEnumerable<T> docs)
{
int index = 0;
Parallel.ForEach(docs, doc =>
{
CreateFolderAndCopyFile(index);
index++;
});
}

当我运行这段代码时,它以以下错误结束:

The process cannot access the file 'c:\testdata\Data00001102\test.pdf' because it is being used by another process.

但在出现此错误之前,它首先创建了 1111 个新文件夹并复制了 test.pdf 大约 1111 次。

是什么导致了这种行为,如何解决?

编辑:

上面的代码是玩具示例,对于硬编码字符串感到抱歉结论:并行方法速度慢。

明天我会尝试 How to write super-fast file-streaming code in C#? 中的一些方法.

特别是:http://designingefficientsoftware.wordpress.com/2011/03/03/efficient-file-io-from-csharp/

最佳答案

您没有同步对 index 的访问,这意味着您有一场比赛。这就是为什么你有错误。出于说明目的,您可以使用 Interlocked.Increment 避免竞争并保留此特定设计。

private static void Func<T>(IEnumerable<T> docs)
{
int index = -1;
Parallel.ForEach(
docs, doc =>
{
int nextIndex = Interlocked.Increment(index);
CreateFolderAndCopyFile(nextIndex);
}
);
}

但是,正如其他人所建议的那样,ForEach 的替代重载提供循环索引显然是针对此特定问题的更简洁的解决方案。

但是当你让它工作时,你会发现复制文件是 IO 绑定(bind)而不是处理器绑定(bind),我预测并行代码会比串行代码慢。

关于c# - File.Copy in Parallel.ForEach,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9913251/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com