事件[event]_C#
事件(event):
1. 事件是类在发生其关注的事情时用来提供通知的方式。例如,封装用户界面控件的类可以定义一个在单击该控件时发生的事件。控件类不关心单击按钮时发生了什么,但它需要告知派生类单击事件已发生。然后,派生类可选择如何响应。
2. 事件发行者(Publisher):
一个事件发行者,也称作发送者(sender),其实就是一个对象,这个对象会自行维护本身的状态信息。当本身状态信息变动时,便触发一个事件,并通知所有的事件订阅者。
事件订阅者(Subscriber):
对事件感兴趣的对象,也称为接收者(Receiver),可以注册感兴趣的事件,通常需提供一个事件处理程序,在事件发行者触发一个事件后,会自动执行这段代码的内容。
3. 事件的四个步骤:
->①在事件发行者中定义一个事件
->②在事件发行者中触发事件
->③在事件订阅者中定义事件处理程序
->④向事件发行者订阅一个事件
看一段代码:
using System;
//注意下面的四步骤!!!
//事件订阅者
class Subscriber //订阅者
{
private string name;
public Subscriber(string name)
{
this.name = name;
}
//③在事件订阅者中定义事件处理程序
public void Receive(string manazineName) //***在事件订阅中定义事件处理程序
{
Console.WriteLine(name + "订阅已收到" + manazineName);
}
}
//事件发布者
class Publisher //出版社
{
public delegate void PubComputer(string magazineName); //声明事件所需的代理,也就是一委托类型
public delegate void PubLife(string magazineName);
//①在事件发行者中定义一个事件
public event PubComputer OnPubComputer; //事件的声明,也就是定义一个委托类型变量
public event PubLife OnPubLife;
public void issueComputer() //***触发事件的方法
{
if (OnPubComputer != null)
{
Console.WriteLine("发行<<电脑>>杂志");
//②在事件发行者中触发事件
OnPubComputer("电脑杂志"); //***触发一个委托链
}
}
public void issueLife()
{
if (OnPubLife != null)
{
Console.WriteLine("发行<<生活>>杂志");
//②在事件发行者中触发事件
OnPubLife("生活杂志");
}
}
}
class Story
{
static void Main()
{
Publisher Pub = new Publisher();
Subscriber zs = new Subscriber("张三");
Subscriber ls = new Subscriber("李四");
//④向事件发行者订阅一个事件
Pub.OnPubComputer += zs.Receive; //***向事件发行者订阅一个事件
Pub.OnPubComputer += ls.Receive;
Pub.OnPubLife += ls.Receive ;
Pub.issueComputer(); //触发事件
Pub.issueLife();
Console.WriteLine();
Console.WriteLine("a year after");
Pub.OnPubComputer -= ls.Receive;
Pub.issueComputer(); //触发事件
Pub.issueLife();
Console.ReadLine();
}
}
4. NET Framework事件设计准则:
->事件的命名准则应使用PascalCasing命名方式
->声明delegate时,使用void类型当作返回值,EventName事件的事件委托是EventNameEventHandler,事件接受两个传入参数,一律命为sender与e.
->定义一个提供事件数据的类。对类以EventNameEventArgs进行命名,从System.EventArgs派生该类,然后添加所有事件特定的成员。
public delegate void EventNameEventHandler(object sender, EventNameEventArgs e);
->下面的过程说明如何在类中实现事件。如果事件不提供任何数据,也要声明两参数,e参数可以直接使用系统的System.EventArgs类。 如果需要传递数据,则要从System.EventArgs继承一个类, 并把数据放在里面。
public delegate void EventNameEventHandler(object sender , EventArgs e);
public event EventNameEventHandler EventName;
->在引发事件的类中提供一个受保护的方法。以OnEventName进行命名。在该方法中引发该事件:
protected virtual void OnEventName(EventArgs e)
{
If ( EventName != null )
{
EventName(this, e );
}
下面规范化一下上面的代码:
using System;
//注意下面的四步骤!!!
//事件订阅者
class Subscriber //订阅者
{
private string name;
public Subscriber(string name)
{
this.name = name;
}
//③在事件订阅者中定义事件处理程序
public void Receive(object sender,PubEventArgs e) //***在事件订阅中定义事件处理程序
{
Console.WriteLine(e.pubDate +" " +name+ "订阅已收到" + e.magazineName );
}
}
//事件发布者
class PubEventArgs : EventArgs //提供数据的类
{
private readonly string _magazineName;
private readonly DateTime _pubDate;
public PubEventArgs(string magazineName, DateTime pubDate)
{
_magazineName = magazineName;
_pubDate = pubDate;
}
public string magazineName
{
get { return _magazineName; }
}
public DateTime pubDate
{
get { return _pubDate; }
}
}
class Publisher //出版社
{
public delegate void PubComputerEventHandler(object sender,PubEventArgs e); //声明事件所需的代理,也就是一委托类型
public delegate void PubLifeEventHandler(object sender, PubEventArgs e);
//①在事件发行者中定义一个事件
public event PubComputerEventHandler PubComputer; //事件的声明,也就是定义一个委托类型变量
public event PubLifeEventHandler PubLife;
protected virtual void OnPubComputer(PubEventArgs e)
{
PubComputerEventHandler handler = PubComputer;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnPubLife(PubEventArgs e)
{
PubLifeEventHandler handler = PubLife;
if (handler != null)
{
handler(this, e);
}
}
public void issueComputer(string magazineName, DateTime pubDate) //***触发事件的方法
{
Console.WriteLine("发行" + magazineName);
//②在事件发行者中触发事件
OnPubComputer(new PubEventArgs(magazineName, pubDate));
}
public void issueLife(string magazineName, DateTime pubDate) //***触发事件的方法
{
Console.WriteLine("发行" + magazineName);
//②在事件发行者中触发事件
OnPubLife(new PubEventArgs(magazineName, pubDate));
}
}
class Story
{
static void Main()
{
Publisher Pub = new Publisher();
Subscriber zs = new Subscriber("张三");
Subscriber ls = new Subscriber("李四");
//④向事件发行者订阅一个事件
Pub.PubComputer += zs.Receive; //***向事件发行者订阅一个事件
Pub.PubComputer += ls.Receive;
Pub.PubLife += ls.Receive;
Pub.issueComputer("电脑杂志",Convert.ToDateTime ("2006-1-1")); //触发事件
Pub.issueLife("生活杂志", Convert.ToDateTime("2006-1-1"));
Console.WriteLine();
Console.WriteLine("a year after");
Pub.PubComputer -= ls.Receive;
Pub.issueComputer("电脑杂志", Convert.ToDateTime("2007-1-1")); //触发事件
Pub.issueLife("生活杂志", Convert.ToDateTime("2007-1-1"));
Console.ReadLine();
}
}
事件[event]_C#的更多相关文章
- 事件EVENT与waitforsingleobject的使用
事件event与waitforsingleobject的配合使用,能够解决很多同步问题,也可以在数据达到某个状态时启动另一个线程的执行,如报警. event的几个函数: 1.CreateEvent和O ...
- 经典线程同步 事件Event
阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...
- C#事件(event)解析
事件(event),这个词儿对于初学者来说,往往总是显得有些神秘,不易弄懂.而这些东西却往往又是编程中常用且非常重要的东西.大家都知道windows消息处理机制的重要,其实C#事件就是基于window ...
- 【温故知新】c#事件event
从上一篇文章[温故知新]C#委托delegate可知,委托delegate和事件Event非常的相似,区别就是event关键字,给delegate穿上了个“马甲”. 让我们来看官方定义: 类或对象可以 ...
- C#中的委托(Delegate)和事件(Event)
原文地址:C#中的委托(Delegate)和事件(Event) 作者:jiyuan51 把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写的设计模式--观察者(Obs ...
- MFC线程(三):线程同步事件(event)与互斥(mutex)
前面讲了临界区可以用来达到线程同步.而事件(event)与互斥(mutex)也同样可以做到. Win32 API中的线程事件 HANDLE hEvent = NULL; void MainTestFu ...
- 重温委托(delegate)和事件(event)
1.delegate是什么 某种意义上来讲,你可以把delegate理解成C语言中的函数指针,它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m,说白了就是可以把方法当作 ...
- C#总结(二)事件Event 介绍总结
最近在总结一些基础的东西,主要是学起来很难懂,但是在日常又有可能会经常用到的东西.前面介绍了 C# 的 AutoResetEvent的使用介绍, 这次介绍事件(event). 事件(event),对于 ...
- 多线程面试题系列(6):经典线程同步 事件Event
上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的"线程所有权"特性所以关键段只能用于线程的互斥而不能用于同步.本篇介绍用事件Event来尝试解决这个线程同步问题.首先 ...
随机推荐
- Hadoop on Mac with IntelliJ IDEA - 1 解决input path does not exist问题
本文讲述使用IntelliJ IDEA时遇到Hadoop提示input path does not exist(输入路径不存在)的解决过程. 环境:Mac OS X 10.9.5, IntelliJ ...
- Uestc_suibian 暑假集训总结
唉,终于组队了,终于可以只BB了,我就BB,我就不上! 和Xiper以及chenxh组队了- 下面是总结: day1 第一天吃饱喝足,然后就上路了,我一开始就看到了C题大水题,但是我不敢想象这道题居然 ...
- Codeforces Bubble Cup 8 - Finals [Online Mirror] D. Tablecity 数学题
D. Tablecity Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/575/problem/D ...
- 自定义的带tab的可左右滑动的viewpager之二viewpager与fragment不兼容
总的来说,这个TAB用起来还算方便吧 不过随着用的地方多起来,发现了一些问题,比如下面这个界面: TAB1和TAB2都是表单,保存按钮对两个TAB都有效:若当前显示TAB1,点击保存则保存TAB1的f ...
- 进程和cpu的相关知识和简单调优方案
进程就是一段执行的程序,每当一个程序执行时.对于操作系统本身来说,就创建了一个进程,而且分配了相应的资源.进程能够分为3个类别: 1.交互式进程(I/O) 2.批处理进程 (CPU) ...
- linux 下网站压力测试工具webbench
一直在用webbench ,这个linux下的网站压力测试工具.整理下. 笔记本装的ubuntu,其他linux系统也差不多. webbench 需要先安装 ctags,一个vim的阅读插件,可以直接 ...
- Android开发 侧边滑动菜单栏SlidingMenu结合Fragment
SlidingMenu是一个开源项目, https://github.com/jfeinstein10/SlidingMenu .功能是创建侧边滑动菜单栏,效果类似人人Android客户端,可点击按钮 ...
- ABAP OO的八大理由
原贴地址:http://scnblogs.techweb.com.cn/abaplv/archives/127.html 几年前SAP BASIS 4.6为ABAP扩展了OO功能,这是很多传统的ABA ...
- Redis 列表(List)
Redis列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素导列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个 ...
- 谈KVC、KVO(重点观察者模式)机制编程
一不小心,小明在<跟着贝尔去冒险>这个真人秀节目中看到了“一日警察,一世警察”的Laughing哥,整个节目除了贝尔吃牛睾丸都不用刀叉的不雅餐饮文化外,还是镜头少普通话跟小明一样烂的Lau ...