2016-06-28 26 views
0

ファイルを繰り返し処理し、特定のファイル名に達するまで各ファイルの整数に+1を追加するアプリケーションを作成したという問題があります。問題はおそらく.Netはネイティブファイルシステムに直接アクセスしないため、コレクションをいっぱいにしますが、私の場合は数年かかるでしょう、私には260,000個のファイルがあります。繰り返しは2番目のファイルにも届きません。スレッドは完全にフリーズし、エラーも例外もありません。それで、ネイティブファイルシステムに直接アクセスする方法はありますか?ところでC#.Net多数のファイルを反復処理中にフリーズする

private void button1_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     foreach (string file in Directory.GetFiles("\\\\Mypcname-PC\\vxheaven\\malware")) 
     { 
      count++; 
      label1.Text = Convert.ToString(count); 
      if (file.Contains(textBox1.Text)) 
      { 
       label1.Text = Convert.ToString(count) + " reached the file"; 
       break; 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

は、ここに私のコードです。あなたはそれが働いている間、それはリフレッシュできませんUIスレッド上ですべての作業を行っているので、私の悪い英語

よろしく

+3

あなたのコードをお手伝いしたい場合は、コードを示す必要があります。 [あなたの質問を編集する](http://stackoverflow.com/posts/38083668/edit)には、ファイルを繰り返し処理するコードが含まれています。 –

+0

2番目の要素に到達しないと、コード内の問題のように聞こえます。おそらく、あなたがコレクションを変更しているように聞こえるかもしれません。 – Plutonix

+0

私はDirectory.GetFiles()を使用していることを忘れています。 – Yogibear

答えて

10

のため申し訳ありません。バックグラウンドスレッドで作業し、スレッドセーフな方法でUIを更新する必要があります。 Directory.EnumerateFilesに切り替えると、すべてのレコードを配列に格納する必要がないため、最初のファイルの読み込みが高速になります。最後に私はex.Messageex.ToString()に変更しました。これにより、より有用な情報が表示されます。

private async void button1_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     var text = textBox1.Text; 
     var progress = new Progress<string>((x) => label1.Text = x); 
     await Task.Run(() => DoWork(progress, text)); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.ToString()); 
    } 
} 

private void DoWork(IProgress<string> progress, string text) 
{ 
    foreach (string file in Directory.EnumerateFiles("\\\\Mypcname-PC\\vxheaven\\malware")) 
    { 
     count++; 
     progress.Report(Convert.ToString(count)); 
     if (file.Contains(text)) 
     { 
      progress.Report(Convert.ToString(count) + " reached the file"); 
      break; 
     } 
    } 
} 

(エラーがあるかもしれませんので、コードがメモリからWebブラウザで書かれた)

+0

これについては知っていましたが、これが問題になるとは思わなかったので、これをチェックします – Yogibear

+2

UIがブロックされているため動作していないようですが、それが働いていることを教えてください –

+0

さて、プロジェクトにコピーされましたが、唯一の質問は何を追加する必要がありますか? – Yogibear

-1

あなたのアプリケーションので、これまでのWindowsメッセージキューを処理せず、潜在的に非常に時間がかかるループを使用しているように思えますあなたはループ内でやるように指示したことをやっているだけで、おそらく忙しいですが、APPEARはフリーズするかもしれません。試してみてください:

private void button1_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     foreach (string file in Directory.GetFiles("\\\\Mypcname-PC\\vxheaven\\malware")) 
     { 
      count++; 
      label1.Text = Convert.ToString(count); 
      Application.DoEvents(); 
      if (file.Contains(textBox1.Text)) 
      { 
       label1.Text = Convert.ToString(count) + " reached the file"; 
       break; 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 
+1

'Application.DoEvents();'は非常に危険です。あなたが気をつけなければあなたのプログラムの内部状態。最初の選択肢として使用しないでください。 –

+0

これは、元のコードを変更せずに迅速かつ厄介な修正でした。もちろん、あなたのコードは(あなたの答えを投票する)はるかに良いですが、それは完全な書き直しではなく修正です。 ;) – FjodrSo