今天在一个项目上工作时,我在.NET中遇到了这种奇怪的行为。
我正在抓取文件名列表并将它们添加到对象中。但是,我需要根据已知的“坏”名称列表过滤传入的名称,这导致我这样做。 (我不是一个先进的C#编码器,仍然只是学习它。)但是,因为它导致 aspnet_wp.exe 进程无限期地以100%运行,我认为我正在做某事这种语言有问题。
这是我的参考代码:
List<string> localFiles = new List<string>();
// I was worried the object was causing the issue so dumbed it down to this with no changed.
string path = "//<file share>/<dir>/";
// As I commented below yes, it's slow when it works but it's clearly not working when using the if();
List<string> omitNames = new List<string>();
omitNames.Add("Thumbs.db");
// This is the only item in the list when it breaks also.
FileInfo[] localFileList = new DirectoryInfo(path).GetFiles();
foreach ( FileInfo item in localFileList )
{
if(!omitNames.Contains(item.Name))
{
localFiles.Add(path + itemName);
}
}
任何人都可以解释为什么这段代码作为无限循环运行?它看起来真的不应该。此外,我意识到使用List
可能不是最好的方法。还有另一种方法可以干净利落地实施吗?
为if(!){}
注释omitNames
可让代码正常运行。 (虽然显然没有过滤结果。)
更新:有人要求将其放入您可以在下方找到的控制台应用中。然而它完美无缺。另一件事是有人建议我尝试简单地将它与字符串进行比较。但是,如果改为这样,就会发生同样的事情:
if(item.Name != "Thumbs.db")
{
localFiles.Add(path + itemName);
}
Console App(可行):
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LoopKiller
{
class Program
{
static void Main(string[] args)
{
List<string> omitNames = new List<string>();
List<string> localFiles = new List<string>();
omitNames.Add("Thumbs.db");
FileInfo[] localFileList = new DirectoryInfo("c:/test/").GetFiles();
foreach (FileInfo item in localFileList)
{
if (!omitNames.Contains(item.Name))
{
Console.WriteLine("Adding " + item.Name + " to localFiles.");
localFiles.Add(item.Name);
Console.WriteLine("Item added to localFiles.");
}
}
foreach (string item in localFiles)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
}
答案 0 :(得分:2)
这样更快吗?
foreach (string item in Directory.GetFiles("c:/test/", "*.*").Select(Path.GetFileName())
{
if (!omitNames.Contains(item))
{
Console.WriteLine("Adding " + item.Name + " to localFiles.");
localFiles.Add(item.Name);
Console.WriteLine("Item added to localFiles.");
}
}
答案 1 :(得分:1)
尝试使用Directory.EnumerateFiles。如果您只需要文件名作为字符串,那么为什么要获取整个FileInfo?我同意把它放在一个哈希集中。
如果问题出在!omitNames.Contains(item.Name),仍然无济于事。那里有一些奇怪的事情,因为这应该是一个非常快速的电话。
对于161个文件的目录,它在2毫秒内运行,并正确地跳过这两个文件。
public void testFileFilter()
{
string path = @"c:\temp\";
int pathLen = path.Length;
string[] badNames = { "1692.pdf", "readme.htm" };
List<string> goodNames = new List<string>();
string fn;
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
foreach(String fp in System.IO.Directory.EnumerateFiles(path))
{
//System.Diagnostics.Debug.WriteLine(fp);
fn = fp.Substring(pathLen);
//System.Diagnostics.Debug.WriteLine(fn);
if(badNames.Contains(fn))
{
//fn = fp.Substring(pathLen);
}
else
{
goodNames.Add(fn);
}
}
sw.Stop();
System.Diagnostics.Debug.WriteLine(sw.ElapsedMilliseconds.ToString());
System.Diagnostics.Debug.WriteLine(goodNames.Count());
}
答案 2 :(得分:0)
尝试以下方法:
List<string> localFiles = new List<string>();
// I was worried the object was causing the issue so dumbed it down to this with no changed.
string path = "//<file share>/<dir>/";
// As I commented below yes, it's slow when it works but it's clearly not working when using the if();
List<string> omitNames = new List<string>();
omitNames.Add("Thumbs.db");
// This is the only item in the list when it breaks also.
localFiles = (from files in new DirectoryInfo(path).GetFiles() where !omitNames.Contains(files.Name) select path + files.Name).ToList<string>();
至于你为什么遇到这个问题,我不知道。您可以尝试在循环和调试中设置断点。我发现调试可以解决大多数问题。例如,锁定获取文件信息。