我在我的应用程序中使用while(true)循环使用多个线程,现在我想在所有活动线程完成其工作时退出循环。
答案 0 :(得分:5)
假设您有一个线程列表本身,这里有两种方法。
第一个解决方案:
使用带有时间跨度参数的Thread.Join()依次与每个线程同步。返回值告诉您线程是否已完成。
解决第二个问题:
检查Thread.IsAlive()以查看该线程是否仍在运行。
在任何一种情况下,确保主线程为正在运行的线程产生处理器时间,否则你的等待循环将消耗大部分/全部CPU并使你的工作线程饿死。
答案 1 :(得分:1)
您可以使用Process.GetCurrentProcess()。Threads.Count。
答案 2 :(得分:1)
这里有各种各样的方法,但是大多数方法都归结为你改变执行的线程,只要它们离开就做某事(成功或通过异常,你不想做任何事情) )。一种简单的方法可能是使用Interlock.Decrement
来减少计数器 - 如果它为零(或-ve,这可能意味着错误),则释放ManualResetEvent
或Monitor.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();