在.net设计开发过程中事件无疑是用的最多的,下面设计几个类来理解CLR事件工作机制:
C#事件模型应用场景:假设我设计一个送货上门的服务程序,当要送货时我将消息发送给送奶工或者邮递员等。
在构建应用程序时,我们先设计一个名为GoodsManager的类型负责发送消息,为GoodsManager类型定义一个对外提供名为NewGoods的事件。其它类型如"Milk"、“NewsPaper”可以订阅该事件。当GoodsManager接收到新的消息时,他将引发该事件,将消息分发给已订阅事件的对象。各个对象则以自己期望的方式来处理消息。
class Program
{
static void Main(string[] args)
{
GoodsManager gm = new GoodsManager();
Milk milk = new Milk(gm);
NewsPaper paper = new NewsPaper();
paper.Register(gm);
gm.SubmitGoods("Jacky","Lily","送货上门");
Console.WriteLine("**************");
//发生经济危机了取消Milk订阅
milk.UnRegister(gm);
gm.SubmitGoods("lily", "Peter", "送货上门");
Console.ReadLine();
}
/// < summary>
/// 定义一个类型用于存放发送给事件接收者的附加信息
/// < /summary>
internal class NewGoodsEventArgs : EventArgs
{
private readonly String f_From, f_To, f_Desc;
public NewGoodsEventArgs(String from,String to,String desc)
{
f_From = from;
f_To = to;
f_Desc = desc;
}
public String From { get { return f_From; } }
public String To { get { return f_To; } }
public String Desc { get { return f_Desc; } }
}
//定义事件成员管理类
internal class GoodsManager
{
//创建线程同步锁的私有字段
private readonly Object m_eventLock = new Object();
private EventHandler< NewGoodsEventArgs> m_NewGoods;
//增加一个事件成员
public event EventHandler< NewGoodsEventArgs> NewGoods
{
//加私有锁并向委托链表增加一个处理程序
add { lock (m_eventLock) { m_NewGoods += value; } }
//显示实现Remove方法
remove { lock (m_eventLock) { m_NewGoods -= value; } }
}
//引发事件的方法,以通知订阅者对像事件已发生。
protected virtual void OnNewGoods(NewGoodsEventArgs e)
{
EventHandler< NewGoodsEventArgs> temp = m_NewGoods;
if (temp != null)
temp(this,e);
}
//将输入转化为期望事件
public void SubmitGoods(String from, String to, String desc)
{
//构个对象用来通知接受者信息
NewGoodsEventArgs e = new NewGoodsEventArgs(from,to,desc);
//调用虚方法通知事件已发生
OnNewGoods(e);
}
}
//监听事件的类型
internal sealed class Milk
{
public Milk() { }
public Milk(GoodsManager gm)
{
gm.NewGoods += new EventHandler< NewGoodsEventArgs>(Milk_NewGoods);
}
//当新的物品送到时执行此方法
void Milk_NewGoods(object sender, NewGoodsEventArgs e)
{
Console.WriteLine("Accept Milk");
Console.WriteLine("From:{0},To:{1},desc:{2}",e.From,e.To,e.Desc);
}
public void UnRegister(GoodsManager gm)//注销事件
{
gm.NewGoods -= Milk_NewGoods;
}
public void Register(GoodsManager gm) //订阅事件
{
gm.NewGoods += Milk_NewGoods;
}
}
internal sealed class NewsPaper
{
public NewsPaper() { }
public NewsPaper(GoodsManager gm)
{
gm.NewGoods += new EventHandler< NewGoodsEventArgs>(Milk_NewGoods);
}
void Milk_NewGoods(object sender, NewGoodsEventArgs e)
{
Console.WriteLine("Accept News Paper");
Console.WriteLine("From:{0},To:{1},desc:{2}", e.From, e.To, e.Desc);
}
public void UnRegister(GoodsManager gm)
{
gm.NewGoods -= Milk_NewGoods;
}
public void Register(GoodsManager gm)
{
gm.NewGoods += Milk_NewGoods;
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
C#事件模型执行结果:
C#事件模型的例子就介绍到这里。
【编辑推荐】