首页 > 学院 > 开发设计 > 正文

线程系列09,线程的等待、通知,以及手动控制线程数量

2019-11-17 02:52:07
字体:
来源:转载
供稿:网友

线程系列09,线程的等待、通知,以及手动控制线程数量

当一个线程直到收到另一个线程的通知才执行相关的动作,这时候,就可以考虑使用"事件等待句柄(Event Wait Handles)"。使用"事件等待句柄"主要用到3个类: AutoResetEvent, ManualResetEvent以及CountdownEvent(.NET 4.0以后才有)。本篇包括:

※ 一个线程等待另一个线程的通知※ 2个线程互相通知等待※ 一个线程等待队列中的多个任务通知※ 手动控制线程的数量

□ 一个线程等待另一个线程的通知

最简单的情景是:发出信号的线程只发出一次通知,等待的线程收到通知也只做一次事情。等待的线程肯定有一个等待方法,发出信号的线程必须有一个发出信号的方法,AutoResetEvent类提供了相关方法。

    class PRogram
    {
        //true表示将初始状态设置为终止状态
        static EventWaitHandle _wait = new AutoResetEvent(false);
        static void Main(string[] args)
        {
            new Thread(Waiter).Start();
            Thread.Sleep(1000);
            _wait.Set();//发出指示
        }
        static void Waiter()
        {
            Console.WriteLine("一切准备就绪,等待指示!");
            _wait.WaitOne();
            Console.WriteLine("收到指示~~");
        }
    }

42

○ AutoResetEvent就像地铁入口的十字转门,有票插入,就让进,而且每次只让一个人进。○ 当调用WaitOne方法,表示该线程已被阻塞,正在等待信号,就像十字转门旁等待进入的乘客。○ 当调用Set方法,表示发出信号给等待线程,就像十字转门收到车票,乘客可以通过。

关于AutoResetEvent:○ 还可通过这种方式创建AutoResetEvent实例:var auto = new EventWaitHandle(false, EventResetMode.AutoReset);○ 如果调用了Set方法,却没有其它线程调用WaitOne方法,这个handle会一直存在○ 如果调用Set方法多次,却有多个线程调用WaitOne方法,也只能让这些线程挨个接收信号,即每次只有一个线程接收信号○ WaitOne还有几个接收时间间隔参数的重载方法,使用WaitOne(0)可以测试一个wait handle是否已经打开○ GC自动回收wait handles

□ 2个线程互相通知等待

还有一种情形:发出信号的线程要发出多次通知,每一次需要确认等待线程收到后再发下一个通知。大概的过程就是:线程A第一次做事并发出通知,进入等待状态;线程B收到通知,发出通知,通知线程A,线程B进入等待状态;线程A收到线程B的通知,第二次做事并发出通知,进入等待状态......2个线程互相通知,每个线程既是发出信号者,也是等待者。借助AutoResetEvent类可以解决此需求。

    class Program
    {
        static EventWaitHandle _ready = new AutoResetEvent(false);
        static EventWaitHandle _go = new AutoResetEvent(false);
        static readonly object o = new object();
        private static string _msg;
        static void Main(string[] args)
        {
            new Thread(DoSth).Start();
            //第一次等待直到另外一个线程准备好
            _ready.WaitOne();
            lock (o)
            {
                _msg = "你好";
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表