1.事件模型建立在委托的基础上。

2,定义事件编译器会做三个动作,第一个构造具有委托类型的字段,事件发生时会通知这个列表中的委托。

第二个构造的是一个添加关注的方法+=。

   第三个构造是一个注销事件关注的方法-=。

3,一个对象不再希望接收事件通知时应该注销对事件的关注,只要一个对象仍向事件登记了一个方法,这个对象不能垃圾回收,所以你的对象若实现了IDisposable的Dispose方法,应该注销对所有事件的关注。

4,-=,remove一个不存在的委托时,不会报错。

下面是一个定义事件的标准写法:引用http://blog.csdn.net/sun_dragon/article/details/8726681

1,定义一个类型来容纳所有应该发送给事件通知接收者的附加信息

2,定义事件成员

3,定义负责引发事件的方法来通知事件的登记对象

    class PriceChangedEventArgs : EventArgs
{
public readonly decimal LastPrice;
public readonly decimal NewPrice;
public PriceChangedEventArgs(decimal lp, decimal np)
{
LastPrice = lp;
NewPrice = np;
}
}
 /// <summary>
/// 扩展方法,用来封装这个线程的逻辑安全
/// </summary>
public static class EventArgExtensions
{
public static void Raise<TEventArgs>(this TEventArgs e,object sender,ref EventHandler<TEventArgs> eventDelegate)where TEventArgs:EventArgs
{
//Interlocked需要4.5环境
//处于线程安全考虑,现在将委托字段的引用复制到一个临时字段中
EventHandler<TEventArgs> temp = Interlocked.CompareExchange(ref eventDelegate, null, null);
if (temp != null)
temp(sender, e);
}
}
    class Stock//即是广播又是接收
{
decimal price;
//string symbol = "stock";
public event EventHandler<PriceChangedEventArgs> PriceChanged;
public decimal Price
{
get { return price; }
set
{
if (price != value)
{
OnPriceChanged(new PriceChangedEventArgs(price, value));//事件触发
}
price = value;
}
} //简单写法,通常这个就够了
//protected virtual void OnPriceChanged(PriceChangedEventArgs e)
//{
// if (PriceChanged != null)
// PriceChanged(this, e);
//} /// <summary>
/// 线程安全写法,事件主要在单线程中使用,线程安全并不是一个问题,先记下有这个东西
/// 考虑这个线程竞态条件应该意识到一个方法可能在从事件的委托链中移除后得到调用
/// </summary>
/// <param name="e"></param>
protected virtual void OnPriceChanged(PriceChangedEventArgs e)
{
e.Raise(this,ref PriceChanged);
}
}

最后是调用

    class EvenManage
{
static void priceChangeInMain(Object sender, PriceChangedEventArgs e)
{
System.Console.WriteLine(sender.ToString());
System.Console.WriteLine("last price" + e.LastPrice + "\nnew price" + e.NewPrice);
}
public static void text()
{
Stock s = new Stock();
s.Price = 100M;//这时没有调用priceChangeInMain,因为没有添加事件
s.PriceChanged += priceChangeInMain;
s.Price = 200M;//添加完事件之后的触发调用了priceChangeInMain
}
}
 

【CLR in c#】事件的更多相关文章

  1. CLR VIA C#事件

    事件是类型的一个成员,用来在事情发生的时候通知注册了该事件的成员. 事件和观察者模式十分的相似,所以事件应该提供如下几种能力 1.能让对象的方法登记对他的关注 2.能让对象的方法取消对他的关注 3.能 ...

  2. CLR 显示实现事件 EventSet内部管理一个字典

    using System; using System.Collections; using System.Collections.Generic; using System.Linq; using S ...

  3. 有关CLR的初学小整理(可能理解不深刻,望大牛指出)

    1. .Net程序通过CLR去加载运行管理代码, 加载CLR的进程成为“宿主”,通常操作系统加载. 加载CLR的进程也可以为某个DLL,也成为“宿主” 2. 宿主接口使宿主能够对运行库的更多方面进行控 ...

  4. NEsper使用的事件类型 z

    NEsper使用的事件类型来描述事件的类型信息.你的应用在启动时可能预先配置定义事件类型,或者在运行时通过API或EPL语法动态的增加事件类型. EPL中的create schema 的语法允许在运行 ...

  5. .NET 中的委托

    1.1.1 定义 委托是一种引用方法的类型.一旦为委托分配了方法,委托将与该方法具有完全相同的行为.委托方法的使用可以像其他任何方法一样,具有参数和返回值,如下面的示例所示: //Code in C# ...

  6. 动手实现一个适用于.NET Core 的诊断工具

    前言 大家可能对诊断工具并不陌生,从大名鼎鼎的 dotTrace,到 .NET CLI 推出的一系列的高效诊断组件(dotnet trace,dotnet sos,dotnet dump)等, 这些工 ...

  7. 《快来为你的 .NET 应用加个监控吧!》更新版本啦

    目录 导读 三种方式处理监控数据 主动推送 ASP.NET Core 自定义URL .NET diagnostics 自定义监控指标 导读 CZGL.ProcessMetrics 是一个 Metric ...

  8. .NET周报【10月第3期 2022-10-25】

    国内文章 聊一聊被 .NET程序员 遗忘的 COM 组件 https://www.cnblogs.com/huangxincheng/p/16799234.html 将Windows编程中经典的COM ...

  9. JNI详解---从不懂到理解

    转载:https://blog.csdn.net/hui12581/article/details/44832651 Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 C ...

  10. CLR via C#深解笔记五 - 事件

    事件处理实际上是一种具有特殊签名的delegate, 像这个样子:public delegate void EventHandler(object sender, EventArgs e);   类型 ...

随机推荐

  1. selinux

    root@lujie ~]# vim /etc/sysconfig/selinux # This file controls the state of SELinux on the system. # ...

  2. iOS-消息推送机制的实现

    OS消息推送的工作机制可以简单的用下图来概括: Provider是指某个iPhone软件的Push服务器,APNS是Apple Push Notification Service的缩写,是苹果的服务器 ...

  3. Sql Server 保留几位小数的两种做法

    数据库里的 float momey 类型,都会精确到多位小数.但有时候 我们不需要那么精确,例如,只精确到两位有效数字. 1. 使用 Round() 函数,如 Round(@num,2)  参数 2 ...

  4. 查询Oracle中字段名带"."的数据

    SDE中的TT_L线层会有SHAPE.LEN这样的字段,使用: SQL>select shape.len from tt_l; 或 SQL>select t.shape.len from ...

  5. Swift - 初始化Initialization

    Ps:苹果官方文档-Initialization 自定义控件初始化中常见的几种错误(指定构造器和便利构造器)截图:   意思是:1.没有添加重写符override(重写父类方法)2.没有重写initW ...

  6. FragmentPagerAdapter实现刷新

    在fragmentpageadapter的instantiateItem方法里,他会先去FragmentManager里面去查找有没有相关的fragment如果有就直接使用如果没有才会触发fragme ...

  7. Delphi管理多线程之线程局部存储:threadvar

    尽管多线程能够解决许多问题,但是同时它又给我们带来了很多的问题.其中主要的问题就是:对全局变量或句柄这样的全局资源如何访问?另外,当必须确保一个线程中的某些事件要在另一个线程中的其他时间之前(或之后) ...

  8. OCJP(1Z0-851) 模拟题分析(一)11

    Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...

  9. 说说JSON和JSONP,也许你会豁然开朗,含jQuery用例 分类: JavaScript 2014-09-23 10:41 218人阅读 评论(1) 收藏

    前言: 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Sock ...

  10. Macbook Pro安装win7

    1.进入OS X系统,在实用工具中打开Boot Camp助理 2.用磁盘工具对磁盘进行分区,将需要安装win7的分区格式化成FAT格式 3.用Boot Camp对磁盘进行分割,然后插入win7的安装光 ...