在C#中有效管理线程

我有一个应用程序,用户将选择执行许多任务以及最大线程数。 每个任务应该在一个单独的线程上运行。 这是我正在寻找的:

如果用户指定“n小于t”,其中n是最大线程数,t是任务数。 程序应运行“n”个线程,完成后,应通过某种方式通知程序并重复循环,直到完成所有任务。

我的问题是:如何知道所有正在运行的线程已完成其工作,以便我可以重复循环。

我建议使用ThreadPool完成任务。 它的算法通常比你可以手动滚动的效率更高。

现在,有趣的部分将在您的所有线程完成时收到通知。 除非你确实有特定的需求使得这个解决方案不合适,否则应该很容易用CountdownEvent类来实现,这是一种特殊的等待句柄,等待它被发出n次信号。 这是一个例子:

 using System; using System.Linq; using System.Threading; using System.Diagnostics; namespace CSharpSandbox { class Program { static void SomeTask(int sleepInterval, CountdownEvent countDown) { try { // pretend this did something more profound Thread.Sleep(sleepInterval); } finally { // need to signal in a finally block, otherwise an exception may occur and prevent // this from being signaled countDown.Signal(); } } static CountdownEvent StartTasks(int count) { Random rnd = new Random(); CountdownEvent countDown = new CountdownEvent(count); for (int i = 0; i < count; i++) { ThreadPool.QueueUserWorkItem(_ => SomeTask(rnd.Next(100), countDown)); } return countDown; } public static void Main(string[] args) { Console.WriteLine("Starting. . ."); var stopWatch = Stopwatch.StartNew(); using(CountdownEvent countdownEvent = StartTasks(100)) { countdownEvent.Wait(); // waits until the countdownEvent is signalled 100 times } stopWatch.Stop(); Console.WriteLine("Done! Elapsed time: {0} milliseconds", stopWatch.Elapsed.TotalMilliseconds); } } } 

您可能想要使用线程池 。 您(可以)指定池中的线程数,并为其指定任务。 当池中的线程空闲时,它会自动查找要执行的另一个任务。

如果要在没有线程池的情况下执行此操作,可以使用Thread.Join等待线程完成。 那是:

 Thread t1 = new Thread(...); Thread t2 = new Thread(...); t1.Start(); t2.Start(); // Wait for threads to finish t1.Join(); t2.Join(); // At this point, all threads are done. 

当然,如果这是一个交互式应用程序,那么您希望它在线程本身中发生。 如果你想得到花哨,等待线程可以完成其中一个线程的工作(即你启动线程1,然后主线程将完成第二个线程的工作)。

如果这是一个交互式应用程序,那么您可能想要使用BackgroundWorker (使用线程池)。 如果将事件处理程序附加到RunWorkCompleted事件,则在工作程序完成其任务时将通知您。 如果您有多个工作人员,请拥有一个RunWorkCompleted事件处理程序,并跟踪哪些工作人员已发出信号。 当他们都发出信号时,你的程序就可以继续做其他需要做的事情。

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx上的示例应该会给你一个良好的开端。

你能检查每个线程的isAlive()值吗? 如果所有值都等于false,那么您就会知道所有线程都已结束。 此外,还有一种方法可让您的代理人返回自己的状态。

http://msdn.microsoft.com/en-us/library/system.threading.thread.isalive(v=VS.90).aspx