gpt4 book ai didi

c# - C# 中的多线程目录循环

转载 作者:太空狗 更新时间:2023-10-30 00:28:21 25 4
gpt4 key购买 nike

我试图遍历所有文件和文件夹并对所有具有特定扩展名的文件执行操作。这种方法工作正常,但我想让它成为多线程的,因为当处理数万个文件时,它真的很慢,我想使用多线程成像会加快速度。我只是不确定在这种情况下如何使用线程。

doStuff 从文件中读取属性(修改日期等)并将它们插入到 sqlite 数据库中。我在调用扫描方法之前开始一个事务,以便尽可能多地进行优化是。

提供有关如何做到这一点的理论的答案与完整的工作代码答案一样好。

    private static string[] validTypes = { ".x", ".y", ".z", ".etc" };
public static void scan(string rootDirectory)
{
try
{

foreach (string dir in Directory.GetDirectories(rootDirectory))
{

if (dir.ToLower().IndexOf("$recycle.bin") == -1)
scan(dir);
}

foreach (string file in Directory.GetFiles(rootDirectory))
{

if (!((IList<string>)validTypes).Contains(Path.GetExtension(file)))
{
continue;
}


doStuff(file);
}
}
catch (Exception)
{
}
}

最佳答案

假设doStuff是线程安全的,并且您不需要等待整个扫描完成,您可以同时调用 doStuffscan在 ThreadPool 上,像这样:

string path = file;
ThreadPool.QueueUserWorkItem(delegate { doStuff(path); });

您需要创建一个单独的局部变量,因为匿名方法会捕获 file变量本身,并且会在整个循环中看到它的变化。 (换句话说,如果ThreadPool只是在循环到下一个文件后才执行任务,它会处理错误的文件)

但是,阅读您的评论,这里的主要问题是磁盘 IO,所以我怀疑多线程不会有太大帮助。

请注意 Directory.GetFiles对于包含大量文件的目录,执行速度会很慢。 (因为它需要分配一个数组来保存文件名)
如果您使用的是 .Net 4.0,您可以通过调用 EnumerateFiles method 使其更快相反,它使用迭代器返回 IEnumerable<string>在您运行循环时枚举目录。
您还可以避免递归 scan通过传递 SearchOption 使用任一方法调用参数,像这样:

foreach (string file in Directory.EnumerateFiles(rootDirectory, "*", SearchOption.AllDirectories))

这将递归扫描所有子目录,因此您只需要一个 foreach循环。
请注意,这会加剧 GetFiles 的性能问题。 ,因此您可能希望避免这种 .Net 4.0 之前的版本。

关于c# - C# 中的多线程目录循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3293502/

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