当在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. 对比学IT---路由器和linux流量统计的差别

    1. 路由器使用MQC来统计端口入出方向,特定特征的数据流. 显示policy 的统计信息 配置policy: #traffic classifier vlan5traffic operator an ...

  2. SoapUI SoapUI测试WebService协议接口简介

    SoapUI测试WebService协议接口简介 by:授客 QQ:1033553122 1. 创建项目,入口:File -> New SOAP Project,或者右键默认项目Project- ...

  3. Cordova/Ionic开发的Android APP启用Chrome Inspect调试的方法

    Cordova/Ionic开发的Android APP,需要启用WebView的调试模式,才可以在Chrome浏览器中输入chrome://Inspect,然后使用大家熟悉的开发者工具进行调试.不启用 ...

  4. (网页)angularjs中的interval定时执行功能(转)

    转载博客园魔豆: 一个例子,用来显示当前实时时间,1秒钟刷新一次: <!DOCTYPE html> <html ng-app="myApp"> <he ...

  5. Spring Data JPA方法定义规范

    Spring Data Jpa方法定义的规则: (1)简单条件查询 简单条件查询:查询某一个实体类或者集合. 按照Spring Data的规范的规定,查询方法以find | read | get开头, ...

  6. [20180608]Wrong Results with IOT, Added Column and Secondary Index.txt

    [20180608]Wrong Results with IOT, Added Column and Secondary Index.txt --//链接:http://db-oriented.com ...

  7. Java —— 对象

    创建对象 int[] b = new int[30]; 等号右侧:创建了一个数组对象  // 等号左侧:变量 b 称为该对应的引用  // 称作 变量 b 指向了一个对象  // 有时也简称为: b ...

  8. CSS| 框模型-margin

    CSS margin 属性 设置外边距的最简单的方法就是使用 margin 属性. margin 属性接受任何长度单位,可以是像素.英寸.毫米或 em. margin 可以设置为 auto.更常见的做 ...

  9. 用Python做股市数据分析(一)

    本文由 伯乐在线 - 小米云豆粥 翻译.未经许可,禁止转载!英文出处:Curtis Miller.欢迎加入翻译组. 这篇博文是用Python分析股市数据系列两部中的第一部,内容基于我犹他大学 数学39 ...

  10. mysql启动失败一例

    操作系统版本:Ubuntu 13.04 mysql 版本:mysql-server-5.5 现象:突然之前接到报告说数据库启不来了.第一时间查看硬盘空间,看是否硬盘满了.发现空间使用正常. root@ ...