2012-10-10 94 views
0

我正在使用Visual Studio 2010 .NET Windows窗體應用程序。NET Windows窗體應用程序的多線程控制

在這個應用程序中,我需要四個後臺線程進行底層數據傳輸。當所有四個線程完成時,將再次使用四個線程開始另一輪四個基礎數據傳輸。

表單UI需要隨時響應。我的問題是:如何控制四個線程的運行?喜歡:我怎麼知道所有線程都完成了?使用易變的全局計數器?

+0

四個後臺線程是否將結果提供給UI? – Enigmativity

回答

1

要回答有關使用特別是四個線程的問題,下面是使用BackgroundWorker的快速草圖。這裏的想法是設置四個任務,跟蹤正在運行的任務的數量,以及何時完成重新啓動。有關volatile與interlocked的討論,請參閱Stack Overflow問題Volatile vs. Interlocked vs. lock

這會給你你要求的東西(四個線程,響應式UI),但沒有錯誤處理,並且可能還有其他問題。有可能一個BackgroundWorker會掛起(也許你的'數據傳輸'不合適),在這種情況下,你最終會處於不良狀態?

public partial class Form1 : Form { 
    private int workersRunning = 0; 
    private List<BackgroundWorker> workers = new List<BackgroundWorker>(); 

    public Form1() { 
     InitializeComponent(); 
     for (int i = 0; i < 4; i++) { 
      BackgroundWorker worker = new BackgroundWorker(); 
      worker.DoWork += new DoWorkEventHandler(this.worker_DoWork); 
      worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.worker_RunWorkerCompleted); 
      workers.Add(worker); 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) { 
     this.StartWork(); 
    } 

    private void StartWork() { 
     workers.ForEach(worker => worker.RunWorkerAsync()); 
    } 

    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){ 
     Interlocked.Decrement(ref workersRunning); 
     Console.WriteLine("Worker reported completion from thread id " + e.Result); 
     if(this.workersRunning == 0) { 
      Console.WriteLine("All workers are done. Start again"); 
      this.StartWork(); 
     } else { 
      Console.WriteLine(this.workersRunning + " workers are still running."); 
     } 
    } 

    void worker_DoWork(object sender, DoWorkEventArgs e) { 
     Interlocked.Increment(ref workersRunning); 
     int threadId = System.Threading.Thread.CurrentThread.ManagedThreadId; 
     Console.WriteLine("Doing work on thread #" + threadId); 

     Thread.Sleep(new Random().Next(2000, 5000)); 

     e.Result = "Work done on thread id " + threadId; 
    } 
} 
+0

謝謝Jeffrey! – skyfree

+0

隨意作出這個答案,如果這有幫助 –

+0

傑弗裏,我只是想通了,我可以在Stackoverflow標記答案。謝謝! – skyfree

2

.NET 4麻煩提供類Task和統一異步API的高水平相關。因此,您可以安全地從基於BackgroundWorker的設計切換到基於任務的設計,然後您將看到等待所有任務完成後是多麼容易的事情。

請參閱Async Tasks - Simplify Asynchronous Programming with Tasks

+0

謝謝Lex,我會檢查任務工廠 – skyfree

相關問題