• [.net 多线程]AutoResetEvent, ManualResetEvent


    ManualResetEvent:

      通知一个或多个正在等待的线程已发生事件,允许线程通过发信号互相通信,来控制线程是否可心访问资源。

    • Set() : 用于向 ManualResetEvent 发送信号,使其取消阻塞状态(唤醒进程)或者开始阻塞进程,这基于 ManualResetEvent 的初始状态。
    • ReSet() : 将 ManualResetEvent 的状态重置至初始状态(即使用 Set() 方法之前的状态)。
    • WaitOne() : 使 ManualResetEvent 进入阻塞状态,开始等待唤醒信号。如果有信号,则不会阻塞,直接通过。
    • 信号 :  new ManualResetEvent(bool arg) ,arg参数就是信号状态,假如为false,则表示当前无信号阻塞线程;如果为true,则有信号不阻塞。
     1 static ManualResetEvent _munual = new ManualResetEvent(false);
     2 static void Main(string[] args)
     3 {
     4     _munual.Reset();
     5     for (int i = 0; i <= 3; i++)
     6     {
     7         Thread th = new Thread(() =>
     8         {
     9             while (true)
    10             {
    11                 _munual.WaitOne();
    12                 Print();
    13                 Thread.Sleep(1000);
    14             }
    15         });
    16         th.IsBackground = true;
    17         th.Name = "线程" + i;
    18         th.Start();
    19     }
    20 
    21     while (true)
    22     {
    23         Thread.Sleep(2000);
    24         Console.WriteLine($"主线程设置信号量");
    25         _munual.Set();
    26         Thread.Sleep(500);
    27         _munual.Reset();
    28     }
    29 }
    30 
    31 static void Print()
    32 {
    33     Console.WriteLine($"{Thread.CurrentThread.Name}::{DateTime.Now.ToString("hh:mm:ss-fff")}");
    34 }
    ManualResetEvent示例

    AutoResetEvent:

      与ManualResetEvent功能类似。

       AutoResetEvent(bool initialState):构造函数,用一个指示是否将初始状态设置为终止的布尔值初始化该类的新实例。
            false:无信号,子线程的WaitOne方法不会被自动调用
            true:有信号,子线程的WaitOne方法会被自动调用
       Reset ():将事件状态设置为非终止状态,导致线程阻止;如果该操作成功,则返回true;否则,返回false。
       Set ():将事件状态设置为终止状态,允许一个或多个等待线程继续;如果该操作成功,则返回true;否则,返回false。
       WaitOne(): 阻止当前线程,直到收到信号。
       WaitOne(TimeSpan, Boolean) :阻止当前线程,直到当前实例收到信号,使用 TimeSpan 度量时间间隔并指定是否在等待之前退出同步域。   
         WaitAll():等待全部信号。
     1 static void Main(string[] args)
     2 {
     3     int current = 0;
     4     List <AutoResetEvent> events = new List<AutoResetEvent>();
     5     for (int taskid = 0; taskid < 3; taskid++)
     6     {
     7         Task.Factory.StartNew(() =>
     8         {
     9             int curr = Interlocked.Increment(ref current);
    10             AutoResetEvent evt = new AutoResetEvent(false);
    11             events.Add(evt);
    12             Console.WriteLine($"Task[{curr}]: working");
    13             Thread.Sleep(current * 1000);
    14             Console.WriteLine($"Task[{curr}]: exit");
    15             evt.Set();
    16         });
    17     }
    18     Console.WriteLine($"Main wait");
    19     AutoResetEvent.WaitAll(events.ToArray());
    20     Console.WriteLine($"All works are done,Main exit");
    21     Console.ReadKey();
    22 }
    AutoResetEvent示例

    两只比较:

    AutoResetEvent在一个线程Wait通过后,会自动设置为有信号状态重新阻塞线程。而ManualResetEvent要调用Reset方法重置,否则将一直允许后续其他线程通过。

    https://blog.csdn.net/ma_jiang/article/details/78628988

    https://www.cnblogs.com/zhangweizhong/p/6628442.html

  • 相关阅读:
    sl学习
    xc笔记
    1_2_3_4_5 Html-Css
    linux服务器架设--学习笔记
    注解学习
    关于ruby gem源更新安装问题
    css3:2D与3D变形
    css3关键帧动画以及兼容性策略
    css3背景,蒙版,倒影以及过度
    阴影边框以及渐变
  • 原文地址:https://www.cnblogs.com/deepminer/p/9011637.html
Copyright © 2020-2023  润新知