前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >学习|C#的EventHandler的委托使用

学习|C#的EventHandler的委托使用

作者头像
Vaccae
发布2020-08-13 11:26:58
1.9K0
发布2020-08-13 11:26:58
举报
文章被收录于专栏:微卡智享微卡智享

本文长度为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。

代码语言:javascript
复制
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,定义了三个方法。

代码语言:javascript
复制
namespace threaddemo
{
    interface Inftest
    {
        event EventHandler<testEvent> DataReceived;
        void Stop();
        void Start();
    }
}

新建一个CTest的类,继承自Inftest

这个类主要是写了一个实现的方式,其中重写了start和stop的方法,及我们定义的DataReceived的的处理方式

CTest的代码

代码语言:javascript
复制
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的触发事件。

代码语言:javascript
复制
        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);
            }
        }

点击按钮初始化时,使用+=刚才定义的方法进行委托。

代码语言:javascript
复制
        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怎么用于模拟读卡器的运行情况。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微卡智享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • EventHandler使用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档