架构师_程序员_码农网

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 18020|回复: 1

[资料] c#线程学习之ManualResetEvent和AutoResetEvent的区别

[复制链接]
发表于 2018-5-31 14:59:47 | 显示全部楼层 |阅读模式
先来讨论ManualResetEvent,讨论过程中我会穿插一些AutoResetEvent的内容,来做对比:

ManualResetEvent都可以阻塞一个或多个线程,直到收到一个信号告诉ManualResetEvent不要再阻塞当前的线程。

关于ManualResetEvent的资料

.net/c# Thread线程Suspend和Resume过时解决方案
https://www.itsvse.com/thread-4769-1-1.html
(出处: 架构师_程序员)


可以想象ManualResetEvent这个对象内部有一个Boolean类型的属性IsRelease来控制是否要阻塞当前线程。这个属性我们在初始化的时候可以设置它,如ManualResetEvent event=new ManualResetEvent(false);这就表明默认的属性是要阻塞当前线程。

代码举例:

  1. ManualResetEvent _manualResetEvent = new ManualResetEvent(false);



  2. private void BT_Temp_Click(object sender, RoutedEventArgs e)

  3. {

  4.     Thread t1 = new Thread(this.Thread1Foo);

  5.     t1.Start(); //启动线程1

  6.     Thread t2 = new Thread(this.Thread2Foo);

  7.     t2.Start(); //启动线程2

  8.     Thread.Sleep(3000); //睡眠当前主线程,即调用BT_Temp_Click的线程

  9.     _manualResetEvent .Set();   //想象成将IsRelease设为True ——。相对的 .reset()则设置成False;

  10. }



  11. void Thread1Foo()

  12. {

  13.     _manualResetEvent .WaitOne();

  14.     //阻塞线程1,直到主线程发信号给线程1,告知_menuResetEvent你的IsRelease属性已经为true,

  15.     //这时不再阻塞线程1,程序继续往下跑

  16.     MessageBox.Show("t1 end");

  17. }



  18. void Thread2Foo()

  19. {

  20.     _manualResetEvent .WaitOne();

  21.     //阻塞线程2,直到主线程发信号给线程1,告知_menuResetEvent你的IsRelease属性已经为true,

  22.     //这时不再阻塞线程2,程序继续往下跑。t2线程即同时知道

  23.     MessageBox.Show("t2 end");

  24. }
复制代码


注意这里ManualResetEvent和AutoResetEvent的一个重要区别:

manual的话肯定会给线程1和线程2都发送一个信号,而auto只会随机给其中一个发送信号。

为什么一个叫manual而一个叫auto呢?我想这是很多人的疑问,现在我们就来看这个问题。

刚才_manualResetEvent .Set();的这句话我想大家都明白了,可以看做将IsRelease的属性设置为true.线程1中

_manualResetEvent.WaitOne();接收到信号后不再阻塞线程1。在此之后的整个过程中IsRelease的值都是true.如果

想将IsRelease的值回复成false,就必须再调用_manualResetEvent.Reset()的方法。

如果是_autoResetEvent.set(),那么_autoResetEvent.WaitOne()后会自动将IsRelease的值自动设置为false。

这就是为什么一个叫auto(自动),一个叫manual(手动)。

QQ截图20180531145247.jpg QQ截图20180531145320.jpg

测试代码:

  1. static AutoResetEvent autoEvent = new AutoResetEvent(false);
  2.         static void Main(string[] args)
  3.         {
  4.             new Thread(() =>
  5.             {
  6.                 while (true)
  7.                 {
  8.                     autoEvent.WaitOne();
  9.                     Console.WriteLine(DateTime.Now.ToLongTimeString() + "_我被执行了!");
  10.                 }
  11.             })
  12.             { IsBackground = true }.Start();
  13.             new Thread(() =>
  14.             {
  15.                 while (true)
  16.                 {
  17.                     autoEvent.WaitOne();
  18.                     Console.WriteLine(DateTime.Now.ToLongTimeString() + "_我被执行了!222");
  19.                 }
  20.             })
  21.             { IsBackground = true }.Start();
  22.             Thread.Sleep(3000);
  23.             autoEvent.Set();
  24.             Console.ReadKey();
  25.         }
复制代码






上一篇:.NET最快的OOM对象映射组件Tiny Mapper之项目实践
下一篇:C# DEBUG 调试信息打印及输出详解
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
 楼主| 发表于 2024-12-18 20:30:44 | 显示全部楼层
ManualResetEvent 和 AutoResetEvent 都继承于 EventWaitHandle,如下图:

QQ截图20241218202923.jpg

参考:https://learn.microsoft.com/zh-cn/dotnet/api/system.threading.eventwaithandle?view=net-9.0

码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2025-3-21 22:14

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表