vb.net 线程偶尔不会自动关闭_C# 多线程系列(7)手动线程通知

区别与示例

AutoResetEvent 和 ManualResetEvent 十分相似。两者之间的区别,在于前者是自动(Auto),后者是手动(Manua)。

你可以先运行下面的示例,再测试两者的区别。

AutoResetEvent 示例:

    class Program
    {
        // 线程通知
        private static AutoResetEvent resetEvent = new AutoResetEvent(false);

        static void Main(string[] args){
            // 创建线程
            new Thread(DoOne).Start();

            // 用于不断向另一个线程发送信号
            while (true)
            {
                Console.ReadKey();
                resetEvent.Set();           // 发生通知,设置终止状态
            }
        }

        public static void DoOne(){
            Console.WriteLine("① 等待中,请发出信号允许我运行");
            resetEvent.WaitOne();

            Console.WriteLine("② 等待中,请发出信号允许我运行");

            resetEvent.WaitOne();
            Console.WriteLine("③ 等待中,请发出信号允许我运行");

            // ...

            Console.WriteLine("线程结束");
        }
    }

ManualResetEvent 类示例:

    class Program
    {
        private static ManualResetEvent resetEvent = new ManualResetEvent(false);
        static void Main(string[] args){
            new Thread(DoOne).Start();
            // 用于不断向另一个线程发送信号
            while (true)
            {
                Console.ReadKey();
                resetEvent.Set();           // 发生通知,设置终止状态
            }
        }

        public static void DoOne(){
            Console.WriteLine("等待中,请发出信号允许我运行");
            resetEvent.WaitOne();

            // 后面的都无效,线程会直接跳过而无需等待
            resetEvent.WaitOne();
            resetEvent.WaitOne();
            resetEvent.WaitOne();
            resetEvent.WaitOne();
            resetEvent.WaitOne();
            Console.WriteLine("线程结束");
        }
    }

因为 AutoResetEvent 对象在 .WaitOne() 方法等待信号完毕后,会自动重置为非终止状态,相当于高速收费站自动闸门,一辆车过去后,机器自动关闸。

ManualResetEvent 相当于人工闸门,打开后编写人工关闭闸门,不然的话闸门会一直处于打开状态。

ManualResetEvent 主要用于更加灵活的线程信号传递场景。

ManualResetEvent 类

表示线程同步事件,收到信号时,要想下一次依然生效,必须手动重置该事件。

因为 ManualResetEvent 类跟 AutoManualResetEvent 类十分接近,这里就不赘述了。

它们的使用区别主要是:

AutoResetEvent 类,每次 Set() ,跳过一个 WaitOne()。因为会 自动恢复设置,所以下次碰到 WaitOne() 会继续等待。

ManualResetEvent 类, Set() 后,不会重置设置,因此一旦使用了 Set() 后,就会一路放通,不会再等待。

其构造函数如下:

ecd653e29add0cdae5fed665e8a47bbc.png

其常用方法如下:

0bbba3140b3160080216d576de24e958.png

ManualResetEventSlim

ManualResetEventSlim 相对 ManualResetEvent ,当等待时间预计非常短并且事件不跨越进程边界时,可以使用此类来获得比 ManualResetEvent 更好的性能。

从代码使用来看,没有啥区别,主要就是考虑性能下时,两者不同场景。

这里就不对这两个类型赘述了。

﹏﹏﹏﹏

c856ade6072608ecb0e92ee87a1f578e.png

ccefef9b1df4d8ae506002140dc9ab3e.png

7ad4c8a14e01e594af5faeb6580c582d.png

61bd1722c53225a419c55540513e2573.png b9d9fd8df0ffbc9d75ef4cfcb35ff203.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值