2011-11-01 5 views
1

백그라운드 폼이 계속 이동하여 '고정'되지 않도록이 함수 아래에 스레드를 연결하려고합니다. 아무도이 작업을 수행하는 데 도움이 될 수 있습니까?# 재귀 디렉터리 검색을 어떻게 스레드합니까?

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

이 (.NET 4 Task와 가능성, BackgroundWorker로 가능) 백그라운드 스레드로 전체를 넣고에 Control.Invoke 또는 Control.BeginInvoke를 사용 UI를 업데이트하려면 UI 스레드로 마샬링합니다.

GetFiles을 호출하고 UI에서 결과를 사용할 수 없습니다. 적어도 C# 5까지는이 작업을 모두 async/await로 훨씬 쉽게 만들 수 있습니다.하지만 백그라운드 스레드에 "tell "완성 된 UI 스레드와 각 개별 파일이 발견 된 경우에도 마찬가지입니다. 기본적으로 이터레이터 블록을 포기하고 클래스 내에서 count 상태로 유지하거나 UI 스레드가 끝날 때 다시 호출 할 때 총 카운트를보고하도록 백그라운드 스레드를 가져옵니다.

+0

Jon, 내 무지를 용서하지만 스레딩에 정통하지는 않습니다. 기존 정보베이스 나 추가 정보를 제공 할 수 있습니까? 고맙습니다. – Clu

+1

@ user995820 :'Control.Invoke'와'Control.BeginInvoke'에서 리소스를 검색하면 * lots * 예제를 볼 수 있습니다. 여러분이 올린 코드는 꽤 복잡하고 변환하는 데 다소 시간이 걸릴 것입니다 만,'textBox1.BeginInvoke'를 조건부로 호출하는'AddMessage' 메소드를 원할 것입니다.'textBox1.InvokeRequired'를 사용하여 그렇게해야합니다. –

+0

Jon, 대단히 감사합니다. 모든 정보를 제공해 주신 데 대해 감사드립니다. – Clu