c# 怎么等待线程池中所有线程都运行结束在运行主线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# 怎么等待线程池中所有线程都运行结束在运行主线程相关的知识,希望对你有一定的参考价值。

主线程执行
。。。
线程1加入线程池
线程2加入线程池
线程3加入线程池
线程4加入线程池...

主线程等待线程池中加入的线程运行完毕。。。

主线程执行
。。。。

怎么实现上面的步骤?如果线程池只加入一个,那么在线程运行结束调用manulresetevent类的set()方法即可,但是加入一个以上该怎么办呢?

可以参见 WaitHandle.WaitAll 方法。
WaitHandle的命名空间是System.Thread。

可以为每一个线程创建一个

WaitHandle,比如:

WaitHandle[] waitHandles = new WaitHandle[]

new AutoResetEvent(false),
new AutoResetEvent(false),
...
;

然后在每条线程结束时,set与之相对应的那个 WaitHandle,

在主线程中,使用

WaitHandle.WaitAll方法来等待所有的WaitHandle,

比如:
WaitHandle.WaitAll(waitHandles);

以下是MSDN中的示例代码:

using System;
using System.Threading;

public sealed class App

// Define an array with two AutoResetEvent WaitHandles.
static WaitHandle[] waitHandles = new WaitHandle[]

new AutoResetEvent(false),
new AutoResetEvent(false)
;

// Define a random number generator for testing.
static Random r = new Random();

static void Main()

// Queue up two tasks on two different threads;
// wait until all tasks are completed.
DateTime dt = DateTime.Now;
Console.WriteLine("Main thread is waiting for BOTH tasks to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
WaitHandle.WaitAll(waitHandles);
// The time shown below should match the longest task.
Console.WriteLine("Both tasks are completed (time waited=0)",
(DateTime.Now - dt).TotalMilliseconds);

// Queue up two tasks on two different threads;
// wait until any tasks are completed.
dt = DateTime.Now;
Console.WriteLine();
Console.WriteLine("The main thread is waiting for either task to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
int index = WaitHandle.WaitAny(waitHandles);
// The time shown below should match the shortest task.
Console.WriteLine("Task 0 finished first (time waited=1).",
index + 1, (DateTime.Now - dt).TotalMilliseconds);


static void DoTask(Object state)

AutoResetEvent are = (AutoResetEvent) state;
int time = 1000 * r.Next(2, 10);
Console.WriteLine("Performing a task for 0 milliseconds.", time);
Thread.Sleep(time);
are.Set();



// This code produces output similar to the following:
//
// Main thread is waiting for BOTH tasks to complete.
// Performing a task for 7000 milliseconds.
// Performing a task for 4000 milliseconds.
// Both tasks are completed (time waited=7064.8052)
//
// The main thread is waiting for either task to complete.
// Performing a task for 2000 milliseconds.
// Performing a task for 2000 milliseconds.
// Task 1 finished first (time waited=2000.6528).

参考资料:MSDN

参考技术A 您能自己在msdn上先看看thread的相关方法和资料吗。。。。这都是太基础的问题了。。。。

http://www.microsoft.com/china/msdn/

http://msdn.microsoft.com/zh-cn/library/default.aspx

参考资料:http://msdn.microsoft.com/zh-cn/library/default.aspx

7.3.4 - 并发多线程 守护线程

一 守护线程

无论是进程还是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁

需要强调的是:运行完毕并非终止运行

1、对主进程来说,运行完毕指的是主进程代码运行完毕

2、对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕

详细解释:

1、主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束,

2、主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。
from threading import Thread
import time

def foo():
    print(123)
    time.sleep(1)
    print("end123")

def bar():
    print(456)
    time.sleep(3)
    print("end456")

if __name__ == __main__:
    t1=Thread(target=foo)
    t2=Thread(target=bar)

    t1.daemon=True
    t1.start()
    t2.start()
    print("main-------")
技术分享图片
123
456
main-------
end123
end456
运行结果

1. t1.start() 会打印 123

2. t2.start()会打印456

3. print("main-------") 会打印main-------

此时主线程在等待其他非守护进程结束后才结束

以上是关于c# 怎么等待线程池中所有线程都运行结束在运行主线程的主要内容,如果未能解决你的问题,请参考以下文章

c#多线程,怎么等待别的线程都结束?谢谢!!

如何等待java线程池中所有任务完成

7第七周-网络编程-守护进程

子线程怎么不阻塞主线程

c#关闭窗口怎么强制退出所有运行的线程

怎么让当前线程等待另一个线程完成之后再去执行