当在C#使用多线程时就免不了使用AutoResetEvent和ManualResetEvent类,可以理解这两个类可以通过设置信号来让线程停下来或让线程重新启动,其实与操作系统里的信号量很相似(汗,考完考试已经有点忘记了)。下面上代码

class Program
{
const int count = ;
//赋值为false也就是没有信号
static AutoResetEvent myResetEvent = new AutoResetEvent(false);
static int number;
static void Main(string[] args)
{
Thread thread = new Thread(funThread);
thread.Name = "QQ";
thread.Start();
for (int i = ; i < count; i++)
{
Console.WriteLine("first number: {0}",i);
number = i;
//这里是设置为有信号
myResetEvent.Set();
Thread.Sleep();
}
thread.Abort();
} static void funThread()
{
while (true)
{
//执行到这个地方时,会等待set调用后改变了信号才接着执行
myResetEvent.WaitOne();
Console.WriteLine("end {0} number: {1}", Thread.CurrentThread.Name, number);
}
} }

输出结果为

first number:1

end QQ number:1

first number:2

end QQ number:3

.....

简单来说只有调用Set()方法后才能执行WaitOne()后面的代码,AutoResetEvent和ManualResetEvent分别都有Set()改变为有信号 ,Reset()改变为无信号,WaitOne()将会阻塞当前调用的线程,直到有信号为止,即执行了Set()方法,WaitOne()方法还可以带指定时间的参数。

理解了AutoResetEvent后再理解ManualResetEvent也就不难了,AutoResetEvent与ManualResetEvent的区别是,AutoResetEvent.WaitOne()会自动改变事件对象的状态,即AutoResetEvent.WaitOne()每执行一次,事件的状态就改变一次,也就是从有信号变为无信号。而ManualResetEvent则是调用Set()方法后其信号量不会自动改变,除非再设置Reset()方法。

在.Net多线程编程中,AutoResetEvent和ManualResetEvent这两个类经常用到, 他们的用法很类似,但也有区别。Set方法将信号置为发送状态,Reset方法将信号置为不发送状态,WaitOne等待信号的发送。可以通过构造函数的参数值来决定其初始状态,若为true则非阻塞状态,为false为阻塞状态。如果某个线程调用WaitOne方法,则当信号处于发送状态时,该线程会得到信号, 继续向下执行。其区别就在调用后,AutoResetEvent.WaitOne()每次只允许一个线程进入,当某个线程得到信号后,AutoResetEvent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只有继续等待.也就是说,AutoResetEvent一次只唤醒一个线程;而ManualResetEvent则可以唤醒多个线程,因为当某个线程调用了ManualResetEvent.Set()方法后,其他调用WaitOne的线程获得信号得以继续执行,而ManualResetEvent不会自动将信号置为不发送。也就是说,除非手工调用了ManualResetEvent.Reset()方法,则ManualResetEvent将一直保持有信号状态,ManualResetEvent也就可以同时唤醒多个线程继续执行。

上述理论部分理解了,请看下面代码,和上边代码输出结果是一致的:

class Program
{
const int count = ;
//赋值为false也就是没有信号
static ManualResetEvent myResetEvent = new ManualResetEvent(false);
static int number;
static void Main(string[] args)
{
Thread thread = new Thread(funThread);
thread.Name = "QQ";
thread.Start();
for (int i = ; i < count; i++)
{
Console.WriteLine("first number: {0}", i);
number = i;
//这里是设置为有信号
myResetEvent.Set();
Thread.Sleep();
}
thread.Abort();
Console.ReadKey();
} static void funThread()
{
while (true)
{
//执行到这个地方时,会等待set调用后改变了信号才接着执行
myResetEvent.WaitOne();
Console.WriteLine("end {0} number: {1}", Thread.CurrentThread.Name, number);
myResetEvent.Reset();//#此处取消信号 注意
}
} }

看懂了这两处代码,相比就会了解二者的区别了!

C#深入理解AutoResetEvent和ManualResetEvent的更多相关文章

  1. C#理解AutoResetEvent和ManualResetEvent

    当在C#使用多线程时就免不了使用AutoResetEvent和ManualResetEvent类,可以理解这两个类可以通过设置信号来让线程停下来或让线程重新启动,其实与操作系统里的信号量很相似(汗,考 ...

  2. C# 定时器和队列结合,卖包子啦,Timer、 AutoResetEvent、 ManualResetEvent

    再你们得到源码之前,我先做个广告:张家港杰德机械/张家港三兴华轩机械是我一朋友的公司,希望需要做净水,灌装机,拔盖机,封口机,传送带等的朋友光顾. 张家港杰德机械有限公司:http://www.jie ...

  3. 个人对AutoResetEvent和ManualResetEvent的理解(转载)

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

  4. AutoResetEvent和ManualResetEvent理解 z

    AutoResetEvent和ManualResetEvent用于多线程之间代码执行顺序的控制,它们继承自WaitHandle,API相同,但在使用中还是有区别的. 每次使用时虽然理解了,但由于没有去 ...

  5. AutoResetEvent和ManualResetEvent理解

    AutoResetEvent和ManualResetEvent用于多线程之间代码执行顺序的控制,它们继承自WaitHandle,API相同,但在使用中还是有区别的. 每次使用时虽然理解了,但由于没有去 ...

  6. 个人对AutoResetEvent和ManualResetEvent的理解

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

  7. [转]个人对AutoResetEvent和ManualResetEvent的理解

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

  8. C#多线程同步事件及等待句柄AutoResetEvent 和 ManualResetEvent

    最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也 ...

  9. C#AutoResetEvent和ManualResetEvent的区别

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

随机推荐

  1. ssms2014和ssms2016版本错误定位的区别

    偶尔对比起2016以下的版本(比如ssms2014),ssms2016有一个小地方有区别.就是报错的行号有区别 举个例子,下面同样的语句在ssms2014和ssms2016里面运行.就是如下的效果 C ...

  2. Android中的padding和margin的区别

    在Android的布局中,常常有人将padding和margin搞混,他们其实不一样的,padding是该控件的内部距离. magin是该控件与其他控件之间的距离.例如 <LinearLayou ...

  3. C语言编程比赛WBS

  4. IO事件驱动模型

    1:IO事件驱动模型简介 通常,我们写服务器处理模型的程序时,有以下几种模型: (1)每收到一个请求,创建一个新的进程,来处理该请求: (2)每收到一个请求,创建一个新的线程,来处理该请求: (3)每 ...

  5. 获取元素的最终background-color

    一.题目  用JS代码求出页面上一个元素的最终的background-color,不考虑IE浏览器,不考虑元素float情况.(题目copy自网上) 二.题目解析  1.考察底层JavaScript基 ...

  6. JHipster技术简介

    本文简单介绍Jhipster是什么,为什么用Jhipster,怎么用Jhipster. WHAT - 技术栈 JHipster是什么 JHipster是一个开发平台,用于生成,开发,部署Spring ...

  7. enum类使用

    状态常量类使用enum public class TestEnums{ public enum STATUS{ NOMAL("01","正常"), DELETE ...

  8. [MapReduce_4] MapTask 并发数的决定机制

    0. 说明 介绍 && Map 个数 & Reduce 个数指定 && Map 切片计算 1. 介绍 一个 job 的 Map 阶段并行度由客户端在提交 job ...

  9. CentOS7下用firewall-cmd控制端口与端口转发

    1.firewalld 守护进程 2.控制端口/服务 3.伪装IP 4.端口转发 实现目标:服务器A和服务器B都是内网互通的,但是只有服务器A是有外网然后现在做端口转发实现服务器B能使用服务器A的外网 ...

  10. Linux之shell脚本for、while、case语句的高级用法

    1.case语句的用法: [root@ELK-chaofeng test]# cat test3.sh #!/bin/bash while true ;do read -p "please ...