C#AutoResetEvent和ManualResetEvent的区别

1

2

3

一:终止状态和非终止状态

    首先说说线程的终止状态和非终止状态。AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态。true表示终止状态(个人理解也就是可运行状态,根据理解应该是该线程的阻塞终止了),false表示非终止状态。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

        AutoResetEvent _autoResetEvent = new AutoResetEvent(false);

        private void BT_Temp_Click(object sender, RoutedEventArgs e)

        {

            Thread t1 = new Thread(this.Thread1Foo);

            t1.Start();

            Thread.Sleep(3000); //Thread.Sleep(Int32)是批当前进程挂起3000毫秒,与线程t1是一点关系也没有的。

            _autoResetEvent.Set();

        }

        void Thread1Foo()

        {

            _autoResetEvent.WaitOne();

            MessageBox.Show("t1 end");

        }

    这段代码的执行结果,就是3秒钟过后,弹出“t1 end”。

    而如果把:

    AutoResetEvent _autoResetEvent = new AutoResetEvent(false);

    改为:

    AutoResetEvent _autoResetEvent = new AutoResetEvent(true);

    则“t1 end”将会立刻弹出。

    也就是说,在终止状态中,_autoResetEvent.WaitOne()是不会起到阻滞工作线程的作用的。(PS:ManualResetEvent也同样)

二:AutoResetEvent和ManualResetEvent的区别

AutoResetEvent 允许线程通过发信号互相通信。 通常,当线程需要独占访问资源时使用该类。

线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。 如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set来通知资源可用。

调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持      为终止状态。如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。 AutoResetEvent 将立即释放线程并返回到非终止状态

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

     AutoResetEvent _autoResetEvent = new AutoResetEvent(false);

        private void BT_Temp_Click(object sender, RoutedEventArgs e)

        {

            Thread t1 = new Thread(this.Thread1Foo);

            t1.Start();

            Thread t2 = new Thread(this.Thread2Foo);

            t2.Start();

            Thread.Sleep(3000);

            _autoResetEvent.Set();

        }

        void Thread1Foo()

        {

            _autoResetEvent.WaitOne();

            MessageBox.Show("t1 end");

        }

        void Thread2Foo()

        {

            _autoResetEvent.WaitOne();

            MessageBox.Show("t2 end");

        }

    该段代码运行的效果是,过3秒后,要么弹出“t1 end”,要么弹出“t2 end”,不会两个都弹出。也就是说,其中一个进行将会结束,而另一个进程永远不会结束。

代码段3:

        ManualResetEvent _menuRestEvent = new ManualResetEvent(false);

        private void BT_Temp_Click(object sender, RoutedEventArgs e)

        {

            Thread t1 = new Thread(this.Thread1Foo);

            t1.Start();

            Thread t2 = new Thread(this.Thread2Foo);

            t2.Start();

            Thread.Sleep(3000);

            _menuRestEvent.Set();

        }

        void Thread1Foo()

        {

            _menuRestEvent.WaitOne();

            MessageBox.Show("t1 end");

        }

        void Thread2Foo()

        {

            _menuRestEvent.WaitOne();

            MessageBox.Show("t2 end");

        }

    该段代码运行的效果是,过3秒后,“t1 end”和“t2 end”,两个都被弹出。也就是说,两个进程都结束了。

    这个特性就是说,AutoResetEvent只会给一个线程发送信号,而不会给多个线程发送信号。在我们需要同步多个线程的时候,就只能采用ManualResetEvent了。至于深层次的原因是,AutoResetEvent在set()之后,会将线程     状态自动置为false,而ManualResetEvent在Set()后,线程的状态就变为true了,必须手动ReSet()之后,才会重新将线程置为false。这也就是为什么他们的名字一个为Auto,一个为Manual的原因。为了更加充分的验证Manua  lResetEvent的这点特性,我们再来看代码片段4

代码片段4:

    ManualResetEvent _menuRestEvent = new ManualResetEvent(false);

        private void BT_Temp_Click(object sender, RoutedEventArgs e)

        {

            Thread t1 = new Thread(this.Thread1Foo);

            t1.Start();

            Thread t2 = new Thread(this.Thread2Foo);

            t2.Start();

            Thread.Sleep(3000);

            _menuRestEvent.Set();

            //_menuRestEvent.Reset();           

        }

        void Thread1Foo()

        {

            _menuRestEvent.WaitOne();

            MessageBox.Show("t1 step1 end");

            //睡1S,用于等待主线程_menuRestEvent.Reset();

            Thread.Sleep(1000);

            _menuRestEvent.WaitOne();

            MessageBox.Show("t1 step2 end");

        }

        void Thread2Foo()

        {

            _menuRestEvent.WaitOne();

            MessageBox.Show("t2 step1 end");

            //睡1S,用于等待主线程_menuRestEvent.Reset();

            Thread.Sleep(1000);

            _menuRestEvent.WaitOne();

            MessageBox.Show("t2 step2 end");

        }

    在代码片段4中,我们对//_menuRestEvent.Reset()进行了注释,也就是说, _menuRestEvent.Set()后,线程的状态就是true状态的,程序运行的结果是"t1 step1 end"、"t1 step2 end"、"t1 step2 end"、"t2 step2 end"在3秒之后全部弹出。

    而如果我们将//_menuRestEvent.Reset()的注释去掉,会发现"t1 step2 end"和"t2 step2 end"永远不会弹出。除非我们在主线程中再次对_menuRestEvent进行Set()。

AutoResetEvent和ManualResetEvent的区别相关推荐

  1. AutoResetEvent和ManualResetEvent

    首先说说线程的终止状态和非终止状态.AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态.true表示终止状态,false表示非 ...

  2. C#笔记20:多线程之线程同步中的信号量AutoResetEvent和ManualResetEvent

    C#笔记20:多线程之线程同步中的信号量AutoResetEvent和ManualResetEvent 本章概要: 1:终止状态和非终止状态 2:AutoResetEvent和ManualResetE ...

  3. 对AutoResetEvent和ManualResetEvent的理解

    一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方法的官方定义并不好理解,什么终止.非 ...

  4. 个人对AutoResetEvent和ManualResetEvent的理解

    仅个人见解,不对之处请指正,谢谢. 一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方 ...

  5. AutoResetEvent与ManualResetEvent区别

    在.Net多线程编程中,AutoResetEvent和ManualResetEvent这两个类经常用到, 他们的用法很类似,但也有区别.Set方法将信号置为发送状态,Reset方法将信号置为不发送状态 ...

  6. 多线程间通信之AutoResetEvent和ManualResetEvent的原理分析

    AutoResetEvent 允许线程通过发信号互相通信. 通常,当线程需要独占访问资源时使用该类. 线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号. 如果 AutoRe ...

  7. 【深度好文】多线程之WaitHandle--派生EventWaitHandle事件构造-》AutoResetEvent、ManualResetEvent...

    AutoResetEvent/ManualResetEvent 都是继承自 EventWaitHandle ,EventWaitHandle继承自WaitHandle. 在讨论这个问题之前,我们先了解 ...

  8. c# AutoResetEvent和ManualResetEvent

    网上有很多AutoResetEvent和ManualResetEvent的详细介绍,在这里不做过多详细的解释,写下自己的一点心得留作备忘. AutoResetEvent和ManualResetEven ...

  9. AutoResetEvent 与 ManualResetEvent

    闲来无事,把AutoResetEvent 与 ManualResetEvent 两个Event进行了一下实践Demo,毕竟以后会遇到多线程的开发问题,现在有时间把它们好好的先试验一下,这样印象会更深刻 ...

  10. 关于AutoResetEvent 和ManualResetEvent

    在公司的代码里面看到这两个类的使用了,第一次去msdn上的时候,看的一头雾水(关键是没有找对方法) http://www.cnblogs.com/qingyun163/archive/2013/01/ ...

最新文章

  1. 1.5 Kali Linux策略
  2. 身为网络安全的,连BlackMatter勒索软件都不知道,说出去丢不丢人啊
  3. 计算机视觉与深度学习 | 基于控制点的投影畸变图像配准(matlab源码)
  4. 报时功能_现在的智能机都没有内置整点自动报时吗?锤子坚果手机SOS有!
  5. Ext 3.0 +ASP.NET2.0 可视化开发介绍
  6. 为什么玩我的世界老提示Java se错误_我的世界error错误信息 error could解决方法
  7. enum是java关键字吗_enum是java关键字吗?
  8. electron 自定义标题栏_electron+vue制作桌面应用--自定义标题栏
  9. 图形化编程Mixly——RFID智能门禁
  10. 国内汽车车载电源DCDC首家,硬件原理图,软件源码
  11. 大麦DW33D路由器假死
  12. 20190131-JS - Promise使用详解--摘抄笔记
  13. 模仿百思不得姐项目开发总结
  14. kneighbors()返回值indices、distances详解
  15. python中patch的使用
  16. 宏正自动科技发表新款8/16端口双滑轨LCD KVM多电脑切换器
  17. 《程序员的成长课》:少走5年弯路
  18. 《模仿游戏》没有告诉你的图灵真相
  19. java 固定电话_Java正则表达式验证固定电话号码符合性
  20. 前端使用xlsx.core.min.js读取excel内容

热门文章

  1. 嵌入式linux应用开发完全手册(一)
  2. vs2017下载教程
  3. [BJ2006] 狼抓兔子
  4. Typora下载及使用
  5. 2022年最新四川建筑八大员(劳务员)模拟题库及答案
  6. 车辆路径规划问题(VRP问题)
  7. 如何在Mac网页中长截图?苹果电脑网页截图怎么截长图?
  8. NanoHTTPD介绍
  9. 快检员计算机知识,计算机检验员(初/中/高级/技师/高技)
  10. 红linux系统,红帽子linux系统