2011-11-01 92 views
1

我想線程下面的函數,以便背景形式可以繼續移動,不會'凍結',任何人都可以幫助我這樣做?c#你如何線程遞歸目錄搜索?

public IEnumerable<string> GetFiles(string path) 
    { 
     Queue<string> queue = new Queue<string>(); 
     queue.Enqueue(path); 
     while (queue.Count > 0) 
     { 
      path = queue.Dequeue(); 
      try 
      { 
       foreach (string subDir in Directory.GetDirectories(path)) 
       { 
        queue.Enqueue(subDir); 
       } 
      } 
      catch (Exception ex) 
      { 
       richTextBox1.AppendText(ex.Message); 
      } 
      string[] files = null; 
      try 
      { 
       files = Directory.GetFiles(path); 
      } 
      catch (Exception ex) 
      { 
       richTextBox1.AppendText(ex.Message); 
      } 
      if (files != null) 
      { 
       for (int i = 0; i < files.Length; i++) 
       { 
        yield return files[i]; 
       } 
      } 
     } 
    } 

我執行的代碼具有以下按鈕:

private void button1_Click(object sender, EventArgs e) 
    { 
     int count = 0; 
     FolderBrowserDialog dialog = new FolderBrowserDialog(); 
     dialog.ShowDialog(); 
     string selected = dialog.SelectedPath; 

     foreach (string file in GetFiles(selected)) 
     { 
      count++; 
      richTextBox1.AppendText(file + Environment.NewLine); 

     } 
     label2.Text = count.ToString(); 
    } 
+0

這是winforms還是wpf? – SliverNinja

+0

這是winforms。 – Clu

+1

@SliverNinja:WPF何時使用標準的'EventHandler'? ;) –

回答

4

把整個東西進入後臺線程(可能具有BackgroundWorker,可能具有在Task .NET 4),並使用Control.InvokeControl.BeginInvoke到當你想更新用戶界面時,編組回到UI線程。

您將無法直接調用GetFiles並在UI中使用結果 - 至少在C#5之前,使用async/await可以使這一切變得更容易 - 但您可以讓後臺線程「告訴「UI線程完成時 - 以及每個單獨文件被找到時。基本上,放棄迭代器塊,並在類中保持count爲狀態,或者在後臺線程完成時調用回UI線程時報告總計數。

+0

喬恩,原諒我的無知,但我不是很精通線程,你可能能夠提供額外的信息或使用我現有的代碼庫的例子嗎?謝謝。 – Clu

+1

@ user995820:如果你在'Control.Invoke'和'Control.BeginInvoke'上搜索資源,你會發現很多例子。你已經發布的代碼相當複雜,將需要一段時間來進行轉換,但你很可能希望有一個'AddMessage'方法,有條件地調用'textBox1.BeginInvoke' - 它應該使用'textBox1.InvokeRequired',看它是否需要這樣做。 –

+0

喬恩,太好了,謝謝你提供的所有信息,非常感謝。 – Clu