Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过网络优化Dictionary.Enumerate文件_C#_.net_Multithreading_Optimization - Fatal编程技术网

C# 通过网络优化Dictionary.Enumerate文件

C# 通过网络优化Dictionary.Enumerate文件,c#,.net,multithreading,optimization,C#,.net,Multithreading,Optimization,我目前有一个扫描网络共享的程序。为此,它首先枚举共享上的所有文件和目录。这是一个非常缓慢的过程。我目前使用下面的代码,摘自这个网站2011年的答案 static class SafeWalk { public static IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOpt) { try

我目前有一个扫描网络共享的程序。为此,它首先枚举共享上的所有文件和目录。这是一个非常缓慢的过程。我目前使用下面的代码,摘自这个网站2011年的答案

static class SafeWalk
    {
        public static IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOpt)
        {
            try
            {
                var dirFiles = Enumerable.Empty<string>();
                if (searchOpt == SearchOption.AllDirectories)
                {
                    dirFiles = Directory.EnumerateDirectories(path)
                                        .SelectMany(x => EnumerateFiles(x, searchPattern, searchOpt));
                }
                return dirFiles.Concat(Directory.EnumerateFiles(path, searchPattern));
            }
            catch (UnauthorizedAccessException ex)
            {
                Console.WriteLine(ex.Message);
                return Enumerable.Empty<string>();
            }
        }
    }
静态类安全行走
{
公共静态IEnumerable枚举文件(字符串路径、字符串搜索模式、SearchOption searchOpt)
{
尝试
{
var dirFiles=Enumerable.Empty();
if(searchOpt==SearchOption.AllDirectories)
{
dirFiles=目录。枚举目录(路径)
.SelectMany(x=>枚举文件(x,searchPattern,searchOpt));
}
返回dirFiles.Concat(Directory.EnumerateFiles(path,searchPattern));
}
捕获(未经授权的访问例外)
{
控制台写入线(例如消息);
返回可枚举的.Empty();
}
}
}
问题是,程序中的所有其他内容都是多线程的,并针对速度进行了优化。这是唯一一个严重阻碍我前进的领域。枚举网络共享中的文件可能需要20分钟。这是在内联网上,我的机器和服务器之间有千兆位或更高的连接

当我在运行时将网络路径临时映射到一个驱动器时,我确实加快了速度。我能做些什么来加快进度吗?看看资源监视器,它几乎没有使用任何CPU、内存或网络带宽。

这是适合你的东西

为什么速度更快

Directory.GetFiles和DirectoryInfo.GetFiles或Directory.EnumerateFile()有许多缺点。最重要的是,它们会丢弃信息,不允许您同时检索多个文件的信息

在内部,Directory.GetFiles作为Win32 FindFirstFile/FindNext文件函数的包装器实现。这些函数都返回了GetFiles()方法返回文件名时丢弃的每个枚举文件的相关信息。它们还通过一条网络消息检索有关多个文件的信息


FastDirectoryEnumerator保留此信息并将其返回到FileData类中。这大大减少了完成相同任务所需的网络往返次数。

考虑使用PInvoke调用选项
FIND\u FIRST\u EX\u LARGE\u FETCH

您是否经常在高容量下使用相同的搜索参数搜索相同的路径?您可以使用缓存结果吗?如果是这样,我建议添加缓存机制。我们也遇到了类似的情况,尽管我们并没有将其公开得如此笼统和精细,我只是缓存了结果。或者,如果您对此不满意,调用方的逻辑是否可能没有保存结果,而是循环多次调用此方法?

如果您没有访问文件/目录的权限,只使用适当的重载?Directory.EnumerateFiles会引发错误,而不是创建递归方法。如果这样做,它只返回到目前为止发现的70GB中的3MB-(那么我猜你唯一的选择就是下面链接的快速目录枚举器。在C#中重复捕获异常和递归方法比直接枚举要慢……你对这个网络共享有什么样的访问权限?你能远程控制并在那个框上运行代码吗?或者它只是普通的网络共享,只有有限的访问权限仅读取和写入文件?@VikasGupta我没有权限在服务器上运行代码。我对共享中包含的大约98%的文件具有读取/写入权限。某些目录是禁止访问的,即使对我也是如此。不,该项目早于EnumerateFiles/Directory()的添加日期.NET 4.0中的方法。它们解决了完全相同的问题。OP已经在使用它。尝试使用此库:在初始测试中,它比我当前的解决方案慢大约5倍。上次我使用Reflector查看时,FindFirstFile中的信息没有被丢弃。请不要引导人们使用它。
Directory.EnumerateFiles/Directory
方法已经在.NET和更好的版本中。不幸的是,该值对Windows 7无效。@在这种情况下,我建议您编写一个在远程计算机上运行的小应用程序,并公开一个API来枚举目录。然后您可以使用快速本地枚举,并在网络上以不需要的方式高效地流式传输结果n-闲聊的方式。事实上,重读msdn,我想它说它在Windows 7及更高版本中受支持,只是措辞笨拙。而且,我根本无法在远程机器上执行任何代码。该工具应该放在扫描机器上,并且能够扫描网络上的任何其他机器。