学更好的别人,
做更好的自己。
——《微卡智享》
本文长度为3661字,预计阅读10分钟
前言
上一篇发了一个视频,关于车辆通过系统的场景模拟,在这个项目中,主要想介绍一下使用中距离的读卡器对车辆上的RFID卡进行身份识别,其中读卡这块的核心就是用到了EventHandler的委托和线程的处理,看了一下原来的C#文章中,以前没有介绍过EventHandler的委托,所以这篇简单先介绍一下这个,后面的文章会结合EventHandler的委托和线程做一个模拟当时环境小Demo。
EventHandler简介

微卡智享
EventHandler就是一个事件处理器,将一个事件与处理事件的方法联系起来的一种机制。 说人话就是:我是小明,现在想邀请小红出去玩,小红说要吃完饭后才能出来。那原来设计这样的话,我需要定时去小红那看看她吃没吃完饭,这样一直等到她吃完后我们再一起出去,而采用EventHandler委托的话,就是吃饭的事小红自己处理,等吃完后他发送一个消息通知我吃完了,然后我们一起出去就行了。
EventHandler使用
# | 说明 |
---|---|
1 | 声明一个EventArgs的子类,传递参数 |
2 | 声明委托对象,执行方法,将方法绑定委托对象 |
3 | 开启EventHandler的委托 |
EventHandler实现

微卡智享
打开VS后新建了一个threaddemo的项目,这个项目Demo当线程一起讲了后我会发上来。
01
创建EventArgs子类
创建一个testEvent的子类,继承自EventArgs,然后定义了一个字符串和一个整数类型,用于记录返回一内容和当前的ID。
namespace threaddemo
{
public class testEvent :EventArgs
{
public string datastr;
public int id;
public testEvent(string str,int id)
{
datastr = str;
this.id = id;
}
}
}
02
定义接口,写接口实现方法
新建一个inftest的接口,上面是用interface而不是class,定义了三个方法。
namespace threaddemo
{
interface Inftest
{
event EventHandler<testEvent> DataReceived;
void Stop();
void Start();
}
}
新建一个CTest的类,继承自Inftest
这个类主要是写了一个实现的方式,其中重写了start和stop的方法,及我们定义的DataReceived的的处理方式
CTest的代码
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);
}
}
}
}
03
开启委托
在Form的主窗体代码中,定义好了CTest的类。
写一个DataReceived的触发事件。
private void _test_DataReceived(object sender, testEvent e)
{
try
{
TextShowNew(richTextBox1, e.datastr);
int count = -1;
try
{
count = Convert.ToInt32(e.datastr);
}
catch(Exception ex)
{
count = -1;
}
if (count >= 0)
{
CItem item = new CItem(0, count, "测试" + count, DateTime.Now);
ht.checkHashTest(item, 5000);
}
if (!ht.checkDatetime(dtclear, 5000))
{
ht.RemoveHashTableFromTime(5000);
dtclear = DateTime.Now;
}
}
catch (Exception ex)
{
TextShowNew(richTextBox1, ex.Message);
}
}
点击按钮初始化时,使用+=刚才定义的方法进行委托。
private void Openinf()
{
try
{
if (_test != null)
{
_test.Stop();
_test.Dispose();
}
_test = null;
_test = new CTest(idx);
_test.DataReceived += _test_DataReceived;
_test.Start();
TextShowNew(richTextBox1, idx + "开启");
idx++;
}
catch (Exception ex)
{
TextShowNew(richTextBox1, "Error:" + ex.Message, 1);
}
}
完成上面这三步,我们的基本委托就可以实现了。
Demo运行效果
上面的Demo是整个运行的效果,下一篇我们讲线程的时候会整个讲一下这个Demo怎么用于模拟读卡器的运行情况。
完
扫描二维码
获取更多精彩
微卡智享
「 往期文章 」