大力的枕头 · vue 获取 ...· 1 年前 · |
急躁的毛巾 · 在 ASP.NET Core ...· 1 年前 · |
失落的咖啡豆 · 使用问题工具查找和修复问题 - ...· 1 年前 · |
爱听歌的机器人 · Js中JSON.stringify()与JS ...· 1 年前 · |
事件(Event) 基本上说是一个用户操作,如按键、点击、鼠标移动等等,或者是一些提示信息,如系统生成的通知。应用程序需要在事件发生时响应事件。例如,中断。
C# 中使用事件机制实现线程间的通信。
事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模型。
发布器(publisher) 是一个包含事件和委托定义的对象。事件和委托之间的联系也定义在这个对象中。发布器(publisher)类的对象调用这个事件,并通知其他的对象。
订阅器(subscriber) 是一个接受事件并提供事件处理程序的对象。在发布器(publisher)类中的委托调用订阅器(subscriber)类中的方法(事件处理程序)。
在类的内部声明事件,首先必须声明该事件的委托类型。例如:
public delegate void BoilerLogHandler(string status);然后,声明事件本身,使用 event 关键字:
// 基于上面的委托定义事件 public event BoilerLogHandler BoilerEventLog;上面的代码定义了一个名为 BoilerLogHandler 的委托和一个名为 BoilerEventLog 的事件,该事件在生成的时候会调用委托。
using System ;当上面的代码被编译和执行时,它会产生下列结果:
event not fire event fire event fire本实例提供一个简单的用于热水锅炉系统故障排除的应用程序。当维修工程师检查锅炉时,锅炉的温度和压力会随着维修工程师的备注自动记录到日志文件中。
using System ;当上面的代码被编译和执行时,它会产生下列结果:
Logging info: Temperature 100 Pressure 12 Message: O. K // 这种汽车可以发送这些事件 public event CarEngineHandler Exploded; public event CarEngineHandler AboutToBlow; public int CurrentSpeed { get; set; } public int MaxSpeed { get; set; } public string PetName { get; set; } private bool CarIsDead; public Car() MaxSpeed = 100; public Car(string name, int maxSp, int currSp) CurrentSpeed = currSp; MaxSpeed = maxSp; PetName = name; public void Accelerate(int delta) // 如果Car无法使用了,触发Exploded事件 if (CarIsDead) if (Exploded != null) Exploded("sorry,this car is dead"); CurrentSpeed += delta; // 确认已无法使用,触发AboutToBlow事件 if ((MaxSpeed - CurrentSpeed) == 10 && AboutToBlow != null) AboutToBlow("careful buddy ! gonna blow !"); if (CurrentSpeed >= MaxSpeed) CarIsDead = true; Console.WriteLine(@"$CurrentSpeed={CurrentSpeed}");qqqqqqqqqqq
264***7645@qq.com
坛子
113***6278@qq.com
一个最简单的例子,不带参数的事件。是实例 2 的一个简化版:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BoilerEvent_tz class DelegateTest public delegate void delegate_tz(); public event delegate_tz delegate_tz0; public void start() Console.WriteLine("启动事件"); delegate_tz0(); // 得调用该事件呀 Console.ReadKey(); class Program static void Main(string[] args) DelegateTest DelegateTest0 = new DelegateTest(); //DelegateTest0.delegate_tz0 += DelegateTest.delegate_tz(test); // 必须new一下才行,因为它是另外一个类呀 DelegateTest0.delegate_tz0 += new DelegateTest.delegate_tz(test); DelegateTest0.start(); // 启动事件 static public void test() Console.WriteLine("这是一个被注册的函数,按任意键继续..."); Console.ReadKey();
crqq123
ays***q@163.com
using System; namespace CarEvent public class Car // 申明委托 public delegate void CarEngineHandler(string msg); // 创建委托实例Exploded和AboutToBlow事件 public event CarEngineHandler Exploded; public event CarEngineHandler AboutToBlow; //设置属性 public int CurrentSpeed { get; set; } public int MaxSpeed { get; set; } public string PetName { get; set; } public bool CarIsDead;//用于判断是否超速 public Car()//构造函数 MaxSpeed = 100; public Car(string name, int maxSp, int currSp)//构造函数重载 CurrentSpeed = currSp; MaxSpeed = maxSp; PetName = name; public void Accelerate(int delta)//用于触发Exploded和AboutToBlow事件 CurrentSpeed += delta;//"踩油门"加速 if (CurrentSpeed >= MaxSpeed)//判断时速 CarIsDead = true; CarIsDead = false; if (CarIsDead)// 如果Car超速了,触发Exploded事件 if (Exploded != null)//判断是否被委托联系起来 Exploded("sorry,this car is dead");//调用CarDead事件 { //如果没有超速,则提示快要超速并显示实时车速 if ((MaxSpeed - CurrentSpeed) > 0 && (MaxSpeed - CurrentSpeed) <= 10 && AboutToBlow != null)//判断是否被委托联系起来且速度是否接近临界值 AboutToBlow("careful buddy ! gonna blow !");//调用NearDead事件 Console.WriteLine("CurrentSpeed={0}",CurrentSpeed);//显示实时车速 //订阅类书写举例 public class Answer public void CarDead(string msg)//汽车已爆缸事件 Console.WriteLine("sorry,this car is dead"); public void NearDead(string msg)//汽车快要爆缸事件 Console.WriteLine("careful buddy ! gonna blow !"); //主函数书写 public class test static void Main(string[] args) Car c = new Car("奔驰",100,93);//创建实例并初始化,初始速度为93 Answer an = new Answer(); c.Exploded += new Car.CarEngineHandler(an.CarDead);//Exploded"绑定"CarDead c.AboutToBlow += new Car.CarEngineHandler(an.NearDead);//AboutToBlow"绑定"NearDead c.Accelerate(6);//第一次加速,时速小于100,引发的事件为"快要爆缸"并显示实时车速为99 Console.ReadLine();//等待回车键已启动第二次加速 c.Accelerate(2);//第二次加速,时速超过100,引发的事件为"已爆缸",不显示车速 Console.ReadKey();"careful buddy ! gonna blow !" "CurrentSpeed=99" (空行)(一定要记得敲一下回车键,不然不会显示下面字符串) "sorry,this car is dead"
樱花树
100***2797@qq.com
using System; /*功能:当起床铃声响起,就引发学生起床/厨师做早餐两个事件 // 定义一个委托(也可以定义在Ring类里面) public delegate void DoSomething(); // 产生事件的类 public class Ring // 声明一个委托事件 public event DoSomething doIt; // 构造函数 public Ring() // 定义一个方法,即"响铃" 引发一个事件 public void RaiseEvent() Console.WriteLine("铃声响了......."); // 判断事件是否有调用委托(是不是要求叫学生起床,叫厨师做饭) if (null != doIt) doIt(); // 如果有注册的对象,那就调用委托(叫学生起床,叫厨师做饭) }else{ Console.WriteLine("无事发生......."); //没有注册,事件没有调用任何委托 // 学生类( 处理事件类一) public class HandleEventOfStudents // 默认构造函数 public HandleEventOfStudents() //叫学生起床 public void GetUp() Console.WriteLine("[学生]:听到起床铃声响了,起床了。"); // 校园厨师类(处理事件类二) public class HandleEventOfChefs // 默认构造函数 public HandleEventOfChefs() //叫厨师做早餐 public void Cook() Console.WriteLine("[厨师]:听到起床铃声响了,为学生做早餐。"); // 主类 public class ListenerEvent public static void Main(String[] args) Ring ring = new Ring(); // 实例化一个铃声类[它是主角,都是因为它才牵连一系列的动作] ring.doIt += new HandleEventOfStudents().GetUp; // 注册,学生委托铃声类,铃声响起的时候叫我起床. ring.doIt += new HandleEventOfChefs().Cook; // 注册,厨师告诉铃声类,我也委托你叫我什么时候做早餐 ring.RaiseEvent(); // 铃声响起来了,它发现学生和厨师都拜托(注册)了自己,然后它就开始叫学生起床,叫厨师做早餐(一个事件调用了两个委托)你可能发现,上面的注册代码和前面的例子都不一样。这是因为 ring.doIt 本来就是 DoSomething 类型的,C# 会自动把学生类方法转换成相同的类型(猜测,但是上面的代码可以完美运行)。当然上面的注册代码也可以写成和文章例子的一样。 改成这样 ring.doIt += new Ring.DoSomething(new HandleEventOfStudents().GetUp); 这样也可以实现,当然这样的话定义委托的语句就要写在 Ring 类里面了。
dzb
duz***o157@163.com
Heavy
178***58425@163.com
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BoilerEvent_tz class DelegateTest // 发布器类 public delegate void delegate_tz(); public event delegate_tz delegate_tz0; public static void get() Console.WriteLine("这是触发事件的第一个方法,此方法在事件类中"); public void inter() Console.WriteLine("开始调用事件方法"); delegate_tz0(); class Test // 订阅器类 public Test() public void TryEvent() Console.WriteLine("这是触发事件的第三个方法,在订阅器中,这才是正宗的订阅器类"); Console.ReadKey(); class Program //主体函数 程序入口 static void Main(string[] args) DelegateTest DelegateTest0 = new DelegateTest(); //主体函数中根据需求组装事件,组装过程类似委托多播 DelegateTest0.delegate_tz0 += new DelegateTest.delegate_tz(DelegateTest.get); DelegateTest0.delegate_tz0 += new DelegateTest.delegate_tz(Method1); DelegateTest0.delegate_tz0 += new DelegateTest.delegate_tz(new Test().TryEvent); DelegateTest0.inter(); // 执行操作,以触发事件 static public void Method1() Console.WriteLine("这是触发事件的第二个方法,在主体Main函数中");执行输出结果为:
开始调用事件方法 这是触发事件的第一个方法,此方法在事件类中 这是触发事件的第二个方法,在主体Main函数中 这是触发事件的第三个方法,在订阅器中,这才是正宗的订阅器类
bai
229***8988@qq.com
咚伊夏
416***884@qq.com
zy
353***928@qq.com
Oldyoung
yya***lu@163.com
mmcike
271***7143@qq.com
cedar_forest
190***9203@qq.com
Gowcage
gow***e@163.com