【发布时间】:2015-07-26 11:36:28
【问题描述】:
我正在开发一个应用程序,它有时(主要是在重新启动后)必须搜索整个驱动器以检查具有给定扩展名的文件自上次重新启动后是否已更改。
起初一切似乎都按预期工作,但过了一段时间后发现并非对所有用户都适用。他们中的一些人开始抱怨他们的计算机在重新启动后的最初几分钟内几乎被冻结。原因是巨大的磁盘活动 (I\O)。
所以我有一个不寻常的问题,如何减慢完整扫描过程? 我正在使用下面的代码。我应该使用 Sleep 方法还是更改逻辑?
public static IEnumerable<string> GetFiles(string rootFolderPath, Regex fileSearchPattern, SearchOption searchOpt)
{
Queue<string> pending = new Queue<string>();
pending.Enqueue(rootFolderPath);
IEnumerable<string> tmp;
while (pending.Count > 0)
{
rootFolderPath = pending.Dequeue();
tmp = EnumerateFiles(rootFolderPath, searchOpt)
.Where(file => fileSearchPattern.IsMatch(
Path.GetExtension(file)
));
foreach (string file in tmp)
{
yield return file;
}
}
}
public static IEnumerable<string> GetDirectories(string rootFolderPath, string directoryName, Regex directorySearchPattern, SearchOption searchOpt)
{
foreach (string directory in EnumerateDirectories(rootFolderPath, directoryName, searchOpt)
.Where(d => directorySearchPattern.IsMatch(d + @"\")))
{
yield return directory;
}
}
public static IEnumerable<string> EnumerateFiles(string path, SearchOption searchOpt)
{
try
{
var dirFiles = Enumerable.Empty<string>();
if (searchOpt == SearchOption.AllDirectories)
{
dirFiles = System.IO.Directory.EnumerateDirectories(path)
.SelectMany(x => EnumerateFiles(x, searchOpt));
}
return dirFiles.Concat(System.IO.Directory.EnumerateFiles(path));
}
catch (IOException)
{
return Enumerable.Empty<string>();
}
catch (UnauthorizedAccessException)
{
return Enumerable.Empty<string>();
}
}
public static IEnumerable<string> EnumerateDirectories(string parentDirectory, string searchPattern, SearchOption searchOpt)
{
try
{
var directories = Enumerable.Empty<string>();
if (searchOpt == SearchOption.AllDirectories)
{
directories = System.IO.Directory.EnumerateDirectories(parentDirectory)
.SelectMany(x => EnumerateDirectories(x, searchPattern, searchOpt));
}
return directories.Concat(System.IO.Directory.EnumerateDirectories(parentDirectory));
}
catch (IOException)
{
return Enumerable.Empty<string>();
}
catch (UnauthorizedAccessException)
{
return Enumerable.Empty<string>();
}
}
【问题讨论】:
-
所有这些 DIY 递归代码是否有特定原因,而不是仅仅将 AllDirectories 传递给 Directory.EnumerateFiles() ?
-
当我尝试仅使用 Directory.EnumerateFiles() 我收到 UnauthorizedAccessException
-
也许你应该有另一种方法,例如有一个订阅文件更改的服务,请参阅msdn.microsoft.com/en-us/library/… 这样您就不需要在重新启动时打扰用户,我们用户都不太喜欢等待
-
当我尝试仅使用 Directory.EnumerateFiles() 时,我收到 UnauthorizedAccessException 捕获并忽略它!它来自受限制的文件夹..
-
为什么不保留一个计数器来记录你做了多少操作,每 x 操作你做一个
Thread.Sleep(x)e.g.if(counter % 100 == 0) Thread.Sleep(100)。在您的foreach中,您递增计数器。