C#深入理解AutoResetEvent和ManualResetEvent
当在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的更多相关文章
- C#理解AutoResetEvent和ManualResetEvent
当在C#使用多线程时就免不了使用AutoResetEvent和ManualResetEvent类,可以理解这两个类可以通过设置信号来让线程停下来或让线程重新启动,其实与操作系统里的信号量很相似(汗,考 ...
- C# 定时器和队列结合,卖包子啦,Timer、 AutoResetEvent、 ManualResetEvent
再你们得到源码之前,我先做个广告:张家港杰德机械/张家港三兴华轩机械是我一朋友的公司,希望需要做净水,灌装机,拔盖机,封口机,传送带等的朋友光顾. 张家港杰德机械有限公司:http://www.jie ...
- 个人对AutoResetEvent和ManualResetEvent的理解(转载)
仅个人见解,不对之处请指正,谢谢. 一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方 ...
- AutoResetEvent和ManualResetEvent理解 z
AutoResetEvent和ManualResetEvent用于多线程之间代码执行顺序的控制,它们继承自WaitHandle,API相同,但在使用中还是有区别的. 每次使用时虽然理解了,但由于没有去 ...
- AutoResetEvent和ManualResetEvent理解
AutoResetEvent和ManualResetEvent用于多线程之间代码执行顺序的控制,它们继承自WaitHandle,API相同,但在使用中还是有区别的. 每次使用时虽然理解了,但由于没有去 ...
- 个人对AutoResetEvent和ManualResetEvent的理解
一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方法的官方定义并不好理解,什么终止.非 ...
- [转]个人对AutoResetEvent和ManualResetEvent的理解
仅个人见解,不对之处请指正,谢谢. 一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方 ...
- C#多线程同步事件及等待句柄AutoResetEvent 和 ManualResetEvent
最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也 ...
- C#AutoResetEvent和ManualResetEvent的区别
一:终止状态和非终止状态 首先说说线程的终止状态和非终止状态.AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态.true表示 ...
随机推荐
- long数值 转换为时间
项目中,服务器端经常给客户端开发人员传一个长整形的时间数据, 对于一个 长整形 1446801883000,可以明显的看出 是以毫秒为单位的,因为最后有三个零,如果没有连续3个零的话就要判断单位了 那 ...
- 安卓开发中strings.xml的使用
为了使用方便也是为了代码规范化,我们都将文字信息放在res-values-strings.xml中, 因为开发中需要用到将文字的换行,百度了一下,可以将文字段信息直接在strings.xml文件中换行 ...
- Asp.Net Core 使用Quartz基于界面画接口管理做定时任务
今天抽出一点点时间来造一个小轮子,是关于定时任务这块的. 这篇文章主要从一下几点介绍: 创建数据库管理表 创建web项目 引入quarzt nuget 包 写具体配置操作,实现定时任务处理 第一步:创 ...
- recovery 差分升级包制作超时
我们在对android系统升级的时候,可以减少升级包的大小,只升级差异部分,也就是差分包升级,相关的描述可以参考:http://blog.csdn.net/csdn66_2016/article/de ...
- python第二天 列表、元组
今天学习了列表.元组相关的知识:与C中的数组列表相似,元组为只读列表: 以及切片相关操作: #!usr/bin/env python #-*-coding:utf-8-*- # Author calm ...
- CSS| 框模型-border
CSS 边框属性
- 实验吧web解题记录
自以为sql注入掌握的还是比较系统的,然而,做了这些题之后才发现,大千世界无奇不有,真是各种猥琐的思路...还是要多学习学习姿势跟上节奏 登录一下好吗?? http://ctf5.shiyanbar. ...
- 15LaTeX学习系列之---LaTeX里插入数学公式
目录 目录 前言 (一)常用的数学公式命令 ==1.上下标== ==2.矢量== ==3.括号== ==4.符号关系== ==5.三角形符号== ==6.求和与累积== ==7.积分与微分== ==8 ...
- <项目需求规格说明书> - 福大易宝
福大易宝-<项目需求规格说明书> 流程 在开会时统一了项目的开发背景,具体功能,然后在同一个工作环境下进行该说明书的编写. 分工 1.李佳铭.杜宏庆共同负责引言和项目描述的内容. 2.刘双 ...
- java用星星符号打印出一个直角三角形
package debug; public class Demo10 { public static void main(String[] args) { //用星星符号打印出一个直角三角形 for( ...