当所有主题完成时

时间:2011-03-13 14:30:28

标签: c# multithreading

这是我第一次尝试使用多线程,我想知道当我的所有任务组都运行完毕后我怎么知道:

for (int i = 0; i < taskGroups.Count(); i++) {
    ThreadStart t = delegate { RunThread(taskGroups[i]); };
    new Thread(t).Start();
}
if(allThreadsComplete){ //???

}

非常感谢任何帮助

附录:

ThreadStart[] threads = new ThreadStart[taskGroups.Count()];
for (int i = 0; i < taskGroups.Count(); i++) {
    threads[i] = new ThreadStart[]
    threads[i] = delegate { RunThread(taskGroups[i]); };
    new Thread(t).Start();
}
bool threadsComplete = false;
while(!threadsComplete){
    for(int i=0;i<taskGroups.Count();i++){
        if(threads[i].State == complete)
        threadsComplete = true;
    }
}

6 个答案:

答案 0 :(得分:4)

您需要存储所有线程,然后调用Thread.Join()。

这样的事情:

List<Thread> threads = new List<Thread>();
for (int i = 0; i < taskGroups.Count(); i++) {
   int temp = i; //This fixes the issue with i being shared
   Thread thread = new Thread(() => RunThread(taskGroups[temp]));
   threads.Add(thread);
   thread.Start();
}

foreach (var thread in threads) {
    thread.Join();
}

答案 1 :(得分:1)

如果您使用的是3.5,则可以write your own CountdownEvent,如果您使用的是4.0,那么您可以使用内置的CountdownEvent执行以下操作:

CountdownEvent = new CountdownEvent(taskGroups.Count());

for (int i = 0; i < taskGroups.Count(); i++) 
{
    int item = i; // copy i locally
    ThreadStart t = delegate 
    { 
        RunThread(taskGroups[item]); 
        latch.Signal();
    };
    new Thread(t).Start();
}

latch.Wait();

latch.Wait()将导致代码阻塞,直到线程全部完成。此外,您可能希望稍微更改启动线程的方式:

CountdownEvent = new CountdownEvent(taskGroups.Count());

for (int i = 0; i < taskGroups.Count(); i++) 
{
    int item = i; // copy i locally
    Thread t = new Thread(()=>
    { 
        RunThread(taskGroups[item]); 
        latch.Signal();
    });
    t.IsBackground = true;
    t.Start();
}

latch.Wait();

请注意,我正在将线程设置为后台:这是您的应用程序在退出时挂起而不是所有线程都已完成(即防止ghost或守护程序线程)。

答案 2 :(得分:0)

您可以查看每个ThreadState对象的Thread属性。

答案 3 :(得分:0)

您可以使用Thread.Join确保每个单独的线程都已运行完毕。

答案 4 :(得分:0)

您可以将公共静态整数字段添加到主线程中,在每个子线程中,当它完成时将其增加1,然后在主线程中等待(在循环中),直到该变量等于taskGroups.Count()

答案 5 :(得分:0)

首先考虑使用Task切换到新的异步模式。

无论如何,如果您想等待所有线程,可以拨打Thread.Join

var threads = new List<Thread>();    
for (int i = 0; i < taskGroups.Count(); i++) {
    ThreadStart t = delegate { RunThread(taskGroups[i]); };
    var thread = new Thread(t);
    threads.Add(thread);
    thread.Start();
}

threads.ForEach(a => a.Join());

请记住,您还可以传递一个超时参数,该参数只有在传输时间不超过您传入的时间后才会等到线程完成。