1

今日プロジェクトに取り組んでいるときに、.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(!){}for をコメントアウトするとomitNames、コードを正しく実行できます。(もちろん、結果はフィルタリングされていません。)

更新:以下にあるコンソール アプリにこれを配置するように要求されました。しかし、それは完全に機能します。もう 1 つのことは、単純に文字列と比較してみることを誰かが提案したことです。しかし、これを次のように変更すると、まったく同じことが起こります。

if(item.Name != "Thumbs.db")
{
    localFiles.Add(path + itemName);
}

コンソール アプリ (動作):

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();

    }
}
}
4

3 に答える 3

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.");
        }
    }
于 2012-08-09T21:28:03.040 に答える
1

Directory.EnumerateFiles を試してください。ファイル名を文字列としてのみ必要な場合、なぜ FileInfo 全体を取得するのでしょうか? そして、それをハッシュセットに入れることに同意します。

Directory.EnumerateFiles

問題が !omitNames.Contains(item.Name) にある場合、それでも解決しません。非常に高速な呼び出しであるため、何か奇妙なことが起こっています。

これは、161 ファイルのディレクトリに対して 2 ミリ秒で実行され、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());
    }    
于 2012-08-09T21:23:06.517 に答える
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>();

なぜ問題が発生しているのかわかりません。ループにブレークポイントを設定してデバッグしてみてください。デバッグによってほとんどの問題が明らかになることがわかりました。たとえば、ファイル情報の取得をロックしています。

于 2012-08-09T21:41:11.043 に答える