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. IOS-ARC和垃圾回收机制

    ARC是编译层面的东西,垃圾回收是程序运行以后的机制,两者不可混为一谈 苹果觉得垃圾回收这种严重影响电源使用效率的特性,同移动设备天生的实时性是相冲突的.但是在iOS 5当中苹果引入了自动内存管理机制 ...

  2. php正则表达式、数组

    <?php $s = "he8llo5wor6ld"; $s = preg_replace("/\d/","#",$s);按照正则表达 ...

  3. CSS设置超出指定宽度自动换行

    一.背景 最近项目中有用到在div中显示用户反馈的信息,是指定宽度的div,超出要自动换行,开始写好后感觉应该没什么问题,后来自己随便输入测试数据的时候发现:如果是纯字母或者是纯数字就会出现超出了也不 ...

  4. mongodb配置文件.conf

    启动方式 ./bin/mongod -f MongoDB.conf 会看到 about to fork child process, waiting until server is ready for ...

  5. Redis内存管理(二)

    上一遍详细的写明了Redis为内存管理所做的初始化工作,这篇文章写具体的函数实现. 1.zmalloc_size,返回内存池大小函数,因为库不同,所以这个函数在内部有很多的宏定义,通过具体使用的库来确 ...

  6. Mysql之INFORMATION_SCHEMA解析1

    INFORMATION_SCHEMA库是Mysql提供的一个系统库,保存了数据库的原数据,方便用户监控与管理Msyql. 现在单说与INNODB相关的库:INNODB_SYS_TABLES,INNOD ...

  7. c_test

    1.int a[][4]={0,0};与int a[3][4] = {0}; 元素不够的就以位模式初始化为0 a[第一维][第二维] 的大小,也就是最多存几个 int a[][3]={1,2,3,4, ...

  8. android DisplayMetrics 获取屏幕分辨率

    Android 提供DisplayMetircs 类可以很方便的获取分辨率.下面介绍 DisplayMetics 类: Andorid.util 包下的DisplayMetrics 类提供了一种关于显 ...

  9. 【转载】 Python 调整屏幕分辨率

    转载来自: http://www.cnblogs.com/fatterbetter/p/4115423.html 需要用windows的api,ChangeDisplaySettings 实现代码如下 ...

  10. iscroll 4.0 滚动(水平和垂直)

    1.概述 iscroll 专注于页面滚动js.Iscroll滚动做的挺好,特别是针对手机网页(android.iphone)正好弥补手动滑屏的遗缺,而今研究一番,把代码贴出来,供大家参考. 2.isc ...