如何确定子线程是否已完成

时间:2010-03-08 05:50:39

标签: c# .net multithreading

我在我的应用程序中使用while(true)循环使用多个线程,现在我想在所有活动线程完成其工作时退出循环。

6 个答案:

答案 0 :(得分:5)

假设您有一个线程列表本身,这里有两种方法。

第一个解决方案:

使用带有时间跨度参数的Thread.Join()依次与每个线程同步。返回值告诉您线程是否已完成。

解决第二个问题:

检查Thread.IsAlive()以查看该线程是否仍在运行。

在任何一种情况下,确保主线程为正在运行的线程产生处理器时间,否则你的等待循环将消耗大部分/全部CPU并使你的工作线程饿死。

答案 1 :(得分:1)

您可以使用Process.GetCurrentProcess()。Threads.Count。

答案 2 :(得分:1)

这里有各种各样的方法,但是大多数方法都归结为你改变执行的线程,只要它们离开就做某事(成功或通过异常,你不想做任何事情) )。一种简单的方法可能是使用Interlock.Decrement来减少计数器 - 如果它为零(或-ve,这可能意味着错误),则释放ManualResetEventMonitor.Pulse一个对象;在任何一种情况下,原始线程都将等待该对象。许多此类方法是discussed here

当然,查看4.0中的TPL位可能更容易,这里提供了许多新选项(尤其是PLINQ中的Parallel.For之类的东西)。

如果您正在使用同步工作队列,那么也可以将该队列设置为关闭(排空)本身,并等待队列为空?这里假设您的工作线程正在执行以下操作:

T workItem;
while(queue.TryDequeue(out workItem)) { // this may block until either something
   ProcessWorkItem(workItem);           // todo, or the queue is terminated
}
// queue has closed - exit the thread

在这种情况下,一旦队列为空,所有工作线程都应该已经处于自杀状态。

答案 3 :(得分:0)

您可以使用Thread.Join()Join方法将阻塞调用线程,直到线程(调用Join方法的线程)终止。

因此,如果您有一个线程列表,那么您可以遍历并在每个线程上调用Join。只有当所有线程都已死时,你才会退出。像这样:

for(int i = 0 ;i < childThreadList.Count; i++)
{
    childThreadList[i].Join();
}
///...The following code will execute when all threads in the list have been terminated...///

答案 4 :(得分:0)

我发现使用Join()方法是最干净的方法。我经常使用多个线程,每个线程通常同时从不同的数据源(Informix,Oracle和SQL)加载数据。一个简单的循环,如上所述,在每个线程对象上调用Join()(我存储在一个简单的List对象)工作!!!

Carlos Merighe。

答案 5 :(得分:0)

我更喜欢使用HashSet of Threads:

// create a HashSet of heavy tasks (threads) to run
HashSet<Thread> Threadlist = new HashSet<Thread>();
Threadlist.Add(new Thread(() => SomeHeavyTask1()));
Threadlist.Add(new Thread(() => SomeHeavyTask2()));
Threadlist.Add(new Thread(() => SomeHeavyTask3()));

// start the threads
foreach (Thread T in Threadlist)
  T.Start();

// these will execute sequential
NotSoHeavyTask1();
NotSoHeavyTask2();
NotSoHeavyTask3();

// loop through tasks to see if they are still active, and join them to main thread
foreach (Thread T in Threadlist)
  if (T.ThreadState == ThreadState.Running)
    T.Join();

// finally this code will execute
MoreTasksToDo();