2012-10-10 71 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

相关问题