学习|C#线程中AutoResetEvent的使用
学更好的别人,
做更好的自己。
——《微卡智享》
本文长度为3106字,预计阅读8分钟
前言
前一篇《学习|C#的EventHandler的委托使用》介绍了EventHandler的简单使用,本篇主要介绍线程中的AutoResetEvent来实现整个读卡器的操作过程。
视频场景
读卡器操作
微卡智享
与读卡器的对接也是调用的读卡器厂家的动态库,根据读卡器厂家的设备操作流程:
其实从上面的读卡器操作流程来看,也能看出来为什么我们上一篇文章要讲EventHandler了,这样就可以把读卡的逻辑和读到卡数据后的业务逻辑进行分开了。话不多说,正篇开始。
AutoResetEvent简介
微卡智享
AutoResetEvent对象用来进行线程同步操作,AutoResetEvent类继承waitHandle类。waitOne()方法就继承来自waitHandle类。
AutoResetEvent的主要方法
# |
主要方法 |
---|---|
1 |
AutoResetEvent(bool initialState):构造函数,参数false:无信号,子线程的WaitOne方法不会被自动调用 true:有信号,子线程的WaitOne方法会被自动调用 |
2 |
Reset ():将事件状态设置为非终止状态,导致线程阻止;如果该操作成功,则返回true;否则,返回false。 |
3 |
Set ():将事件状态设置为终止状态,允许一个或多个等待线程继续;如果该操作成功,则返回true;否则,返回false。 |
4 |
WaitOne():阻止当前线程,直到收到信号。 |
5 |
WaitOne(TimeSpan, Boolean) :阻止当前线程,直到当前实例收到信号,使用 TimeSpan 度量时间间隔并指定是否在等待之前退出同步域。 |
上面就是AutoResetEvent的主要方法,从上面的主要方法中我们可以看到,实现读卡器每100耗秒进行检测,原来通过线程是sleep进行处理,现在可以使用WaitOne的方式,并且通过这个方法,我们可以在外部实现读卡器重连的调用。
本项目场景
本项目(开头视频)中因为读卡器使用的网络通讯,所以我们要考虑出现异常情况下实现读卡器自动重连。
- 如果存在网络中断的时候我们要考虑到自动重连。
- 在车牌识别时发现是会员,但是没有读到卡信息,有可能读卡器出现异常,也要进行自动重连。
根据上面的情况,我们就可考虑除了读卡数据异常时需要自动重新连接,还要在外部接口中封装一个函数,可以从外部直接调用重连读卡器。实际项目中对读卡器的操作没法贴上来,这里我们就接着一个DEMO,模拟一下这个场景。
代码演示
微卡智享
接着我们的threaddemo,在CTest的类中我们开始改造。
先定义一个AutoResetEvent,和等待的毫秒waitTime。
然后定义一个Reset的方法,模拟读卡器重启。
原来的停止方法中加入isRunning的开关,再调用exitEvent的Reset和Set,这样就可以区分是重启还是终止。
我们在循环的操作里面加入一个随机数生成,取值为0到13内
- 如果取值的数字小于10,那就正常发送数据。
- 如果取值的数字等于10,那就直接抛出异常,然后在异常中内部模拟Reset重连读卡器。
- 如果取值的数字大于10,也直接进行重连,只不过不用抛出异常。
代码
using System;using System.Collections.Generic;using System.Drawing.Text;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;
namespace threaddemo{ public class CTest : Inftest,IDisposable { public int id;
private AutoResetEvent exitEvent;
private Thread thread;
private int waitTime = 100;
private bool disposed = false;
private bool IsRunning;
public int cs = 0; public CTest(int _id) { id = _id; exitEvent = new AutoResetEvent(false); thread = new Thread(ReadThreadRun); thread.IsBackground = true; }
public event EventHandler<testEvent> DataReceived;
public void Dispose() { // Dispose(true); GC.SuppressFinalize(this); }
protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { try { Stop();
} catch (Exception) {
} } disposed = true; } }
public void Start() { IsRunning = true; thread.Start(); }
public void Stop() { IsRunning = false; exitEvent.Reset(); exitEvent.Set(); RaiseDataReceived("手动停止"); }
public void Reset() { exitEvent.Reset(); exitEvent.Set(); }
public void setcs(int _cs) { cs = _cs;
}
private void RaiseDataReceived(string msg) { DataReceived?.Invoke(this, new testEvent(msg, id)); }
/// <summary> /// 接收线程 /// </summary> private void ReadThreadRun() { while (IsRunning) { try { if (exitEvent.WaitOne(waitTime)) { if (IsRunning) { Thread.Sleep(1000); id++; if (id % 5 == 0) { throw new Exception("余数:0"); }else if (id % 5 == 1) { try { throw new Exception("故意出错"); } catch(Exception ex) { RaiseDataReceived(ex.Message); Reset(); } } RaiseDataReceived("状态:重启"); } else { Thread.Sleep(1000); RaiseDataReceived("停止"); } }
Random rd = new Random(); int count = rd.Next(0, 13); if (count < 10) { RaiseDataReceived(count.ToString()); } else if (count == 10) { throw new Exception("throw 数字:" + count); } else { RaiseDataReceived("数字:" + count + " Reset"); Reset(); } } catch (Exception ex) { RaiseDataReceived("error " + ex.Message); Reset(); }
//Thread.Sleep(100); } } }}
实现效果
源码地址
https://github.com/Vaccae/EventHandlerDemo.git
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- php+js实现裁剪任意形状图片
- keras实现theano和tensorflow训练的模型相互转换
- python中round函数如何使用
- PHP array_reduce()函数的应用解析
- php微信公众号开发之简答题
- php5.x禁用eval的操作方法
- php微信公众号开发之图片回复
- php微信公众号开发之答题连闯三关
- swoole_process实现进程池的方法示例
- golang实现php里的serialize()和unserialize()序列和反序列方法详解
- keras 实现轻量级网络ShuffleNet教程
- Python应用实现处理excel数据过程解析
- Python实现爬取并分析电商评论
- python中怎么表示空值
- Keras自动下载的数据集/模型存放位置介绍