C#多线程(7):手动线程通知
区别与示例
AutoResetEvent 和 ManualResetEvent 十分相似。两者之间的区别,在于前者是自动(Auto),后者是手动(Manua)。
你可以先运行下面的示例,再测试两者的区别。
AutoResetEvent 示例:
class Program
{
// 线程通知
private static AutoResetEvent resetEvent = new AutoResetEvent(false);
static void Main(string[] args)
{
// 创建线程
new Thread(DoOne).Start();
// 用于不断向另一个线程发送信号
while (true)
{
Console.ReadKey();
resetEvent.Set(); // 发生通知,设置终止状态
}
}
public static void DoOne()
{
Console.WriteLine("① 等待中,请发出信号允许我运行");
resetEvent.WaitOne();
Console.WriteLine("② 等待中,请发出信号允许我运行");
resetEvent.WaitOne();
Console.WriteLine("③ 等待中,请发出信号允许我运行");
// ...
Console.WriteLine("线程结束");
}
}
ManualResetEvent 类示例:
class Program
{
private static ManualResetEvent resetEvent = new ManualResetEvent(false);
static void Main(string[] args)
{
new Thread(DoOne).Start();
// 用于不断向另一个线程发送信号
while (true)
{
Console.ReadKey();
resetEvent.Set(); // 发生通知,设置终止状态
}
}
public static void DoOne()
{
Console.WriteLine("等待中,请发出信号允许我运行");
resetEvent.WaitOne();
// 后面的都无效,线程会直接跳过而无需等待
resetEvent.WaitOne();
resetEvent.WaitOne();
resetEvent.WaitOne();
resetEvent.WaitOne();
resetEvent.WaitOne();
Console.WriteLine("线程结束");
}
}
因为 AutoResetEvent 对象在 .WaitOne() 方法等待信号完毕后,会自动重置为非终止状态,相当于高速收费站自动闸门,一辆车过去后,机器自动关闸。
ManualResetEvent 相当于人工闸门,打开后编写人工关闭闸门,不然的话闸门会一直处于打开状态。
ManualResetEvent 主要用于更加灵活的线程信号传递场景。
ManualResetEvent 类
表示线程同步事件,收到信号时,要想下一次依然生效,必须手动重置该事件。
因为 ManualResetEvent 类跟 AutoManualResetEvent 类十分接近,这里就不赘述了。
它们的使用区别主要是:
AutoResetEvent 类,每次 Set() ,跳过一个 WaitOne()。因为会 自动恢复设置,所以下次碰到 WaitOne() 会继续等待。
ManualResetEvent 类, Set() 后,不会重置设置,因此一旦使用了 Set() 后,就会一路放通,不会再等待。
其构造函数如下:
| 构造函数 | 说明 |
|---|---|
| ManualResetEvent(Boolean) | 用一个指示是否将初始状态设置为终止的布尔值初始化 ManualResetEvent 类的新实例。 |
其常用方法如下:
| 方法 | 说明 |
|---|---|
| Close() | 释放由当前 WaitHandle 占用的所有资源。 |
| Reset() | 将事件状态设置为非终止,从而导致线程受阻。 |
| Set() | 将事件状态设置为有信号,从而允许一个或多个等待线程继续执行。 |
| WaitOne() | 阻止当前线程,直到当前 WaitHandle 收到信号。 |
| WaitOne(Int32) | 阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)。 |
| WaitOne(Int32, Boolean) | 阻止当前线程,直到当前的 WaitHandle 收到信号为止,同时使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。 |
| WaitOne(TimeSpan) | 阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。 |
| WaitOne(TimeSpan, Boolean) | 阻止当前线程,直到当前实例收到信号为止,同时使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。 |
ManualResetEventSlim
ManualResetEventSlim 相对 ManualResetEvent ,当等待时间预计非常短并且事件不跨越进程边界时,可以使用此类来获得比 ManualResetEvent 更好的性能。
从代码使用来看,没有啥区别,主要就是考虑性能下时,两者不同场景。
这里就不对这两个类型赘述了。
C#多线程(7):手动线程通知的更多相关文章
- C#多线程(6):线程通知
目录 AutoRestEvent 类 常用方法 一个简单的示例 解释一下 复杂一点的示例 解释 回顾一下,前面 lock.Monitor 部分我们学习了线程锁,Mutex 部分学习了进程同步,Sema ...
- 20190102(多线程,守护线程,线程互斥锁,信号量,JoinableQueue)
多线程 多进程: 核心是多道技术,本质上就是切换加保存技术. 当进程IO操作较多,可以提高程序效率. 每个进程都默认有一条主线程. 多线程: 程序的执行线路,相当于一条流水线,其包含了程序的具体执行步 ...
- .NET面试题解析(07)-多线程编程与线程同步
系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等, ...
- .NET面试题解析(07)-多线程编程与线程同步 (转)
http://www.cnblogs.com/anding/p/5301754.html 系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实 ...
- C#学习笔记之线程 - 通知Signal
通知事件等待句柄 Signal With EventWaitHandle 事件等待句柄常用于通知.当一个线程等待直到接收到另外一个线程发出的信号.事件等待句柄是最简单的信号结构,它与C#事件无关.有三 ...
- VC中利用多线程技术实现线程之间的通信
当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...
- -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中
本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait( ...
- Python中的多线程编程,线程安全与锁(二)
在我的上篇博文Python中的多线程编程,线程安全与锁(一)中,我们熟悉了多线程编程与线程安全相关重要概念, Threading.Lock实现互斥锁的简单示例,两种死锁(迭代死锁和互相等待死锁)情况及 ...
- 转:java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例
java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例 1.CountDownLatch:一个同步工具类,它允许一个或多个线程一 ...
- Java多线程并发02——线程的生命周期与常用方法,你都掌握了吗
在上一章,为大家介绍了线程的一些基础知识,线程的创建与终止.本期将为各位带来线程的生命周期与常用方法.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程生命周期 一个线程不是被创建了 ...
随机推荐
- 【JS 逆向百例】HN某服务网登录逆向,验证码形同虚设
声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 逆向目标 目标:某政务服务 ...
- Protobuf中如何指定json tag
在 Protocol Buffers (protobuf) 中,可以使用特定的选项来指定生成的 JSON 标签.通过在消息定义中使用 [(json_name)] 选项,可以控制生成的 JSON 字段名 ...
- Leetcode 42题 接雨水(Trapping Rain Water) Java语言求解
题目链接 https://leetcode-cn.com/problems/trapping-rain-water/ 题目内容 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱 ...
- 深度学习应用篇-计算机视觉-图像分类[3]:ResNeXt、Res2Net、Swin Transformer、Vision Transformer等模型结构、实现、模型特点详细介绍
深度学习应用篇-计算机视觉-图像分类[3]:ResNeXt.Res2Net.Swin Transformer.Vision Transformer等模型结构.实现.模型特点详细介绍 1.ResNet ...
- 字节码编程,Javassist篇四《通过字节码插桩监控方法采集运行时入参出参和异常信息》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 字节码编程插桩这种技术常与 Javaagent 技术结合用在系统的非入侵监控中,这样 ...
- P9816 少项式复合幂 题解
题目链接:少项式复合幂 注意到题目的模并不是很大,我们考虑两个核心的性质. \(f(f(x)) \bmod p=f(f(x) \bmod p) \bmod p\),证明直接代入 \(f(x)\) 进去 ...
- CentOS7的udev的绑定规则
客户一套RAC环境是华为的存储,共享盘是/dev/sd*,咋一看还怀疑是没有进行多路径配置,实际和主机工程师是已经配置好的,我们使用upadmin show vlun命令可以查看到: [root@xx ...
- Linux中单引号和双引号的区别
区别:单引号属于强引用,它会忽略所有被引起来的字符的特殊处理,被引用起来的字符会被原封不动的使用:而双引号属于弱引用,它会对一些被引起来的字符进行特殊处理.简单来说,单引号直接输出内部字符串,不解析特 ...
- Spring Boot 1.5.x 结合 JUnit5 进行接口测试
在Spring Boot 1.5.x中,默认使用Junit4进行测试.而在对Controller进行接口测试的时候,使用 @AutoConfigureMockMvc 注解是不能注入 MockMvc 对 ...
- 如何在.NET Core中为gRPC服务设计消息
如何在.NET Core中为gRPC服务设计消息 使用协议缓冲区规范定义gRPC服务非常容易,但从需求转换为.NET Core,然后管理服务的演变时,需要注意几件事. 创建gRPC服务的核心是.pro ...