2011-11-01 38 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