CLR 显示实现事件 EventSet内部管理一个字典
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApplication5
{
public sealed class EventKey { }
public sealed class EventSet
{
//内部管理一个事件的字典,key为每次生成的所以哈希码是不同的,以确认字典的键不会重复
private readonly Dictionary<EventKey, Delegate> m_events = new Dictionary<EventKey, Delegate>();
/// <summary>
/// Monitor.Enter线程安全,在指定对象上获取排它锁
/// </summary>
/// <param name="eventKey"></param>
/// <param name="handle"></param>
public void Add(EventKey eventKey,Delegate handle)
{
//获取指定对象上的排它锁,线程安全,确保我在增加一个键值对的时候不会发生导致线程不安全的情况
Monitor.Enter(m_events);
Delegate d;
//获取指定键相关联的值,关键是这样可以防止字典的键不存在时,还要写代码去判断键是否存在的情况
m_events.TryGetValue(eventKey, out d);
//将两个委托的调用列表链接在一起
m_events[eventKey] = Delegate.Combine(d, handle);
//释放指定对象上的排它锁
Monitor.Exit(m_events); }
public void Remove(EventKey eventKey, Delegate handler)
{
Monitor.Enter(m_events);
Delegate d;
if (m_events.TryGetValue(eventKey, out d))
{
//从指定的源上删除某个委托,内部执行多路广播委托,删除后委托链的头部地址会改变
d = Delegate.Remove(d, handler); //删除后还有委托,设置新的头部地址
if (d != null)
{
m_events[eventKey] = d;
}
else
{
m_events.Remove(eventKey);
}
Monitor.Exit(m_events); }
}
//激发事件委托
public void Raise(EventKey eventKey, Object sender, EventArgs e)
{
Delegate d;
Monitor.Enter(m_events);
m_events.TryGetValue(eventKey,out d);
Monitor.Exit(m_events);
if (d != null)
{
d.DynamicInvoke(new object[] {sender,e });
}
} }
public class FooEventArgs : EventArgs { }
public class TypeWithLotsOfEvents
{ private readonly EventSet m_eventSet = new EventSet();
protected EventSet EventSet { get { return m_eventSet; } }
//对于TypeWithLotsOfEvents的每个实例对应的 下列字段key是唯一的
protected static readonly EventKey s_fooEventKey = new EventKey(); public event EventHandler<FooEventArgs> FOO
{
add { m_eventSet.Add(s_fooEventKey, value); }
remove { m_eventSet.Remove(s_fooEventKey, value); }
} protected virtual void OnFOO(FooEventArgs e)
{
m_eventSet.Raise(s_fooEventKey, this, e);
}
public void SimulateFOO()
{
OnFOO(new FooEventArgs());
} }
class Program
{
static void Main(string[] args)
{
TypeWithLotsOfEvents twle = new TypeWithLotsOfEvents();
twle.FOO += Twle_FOO;
twle.SimulateFOO();
Console.ReadKey(); } private static void Twle_FOO(object sender, FooEventArgs e)
{
Console.WriteLine("Hading Foo Event here...");
}
}
}
CLR 显示实现事件 EventSet内部管理一个字典的更多相关文章
- [转]3天搞定的小型B/S内部管理类软件定制开发项目【软件开发实战10步骤详解】
本文转自:http://www.cnblogs.com/jirigala/archive/2010/10/07/1845275.html 2010-10-07 21:39 by 通用C#系统架构, 5 ...
- 关于vue事件监听的一个问题
由于新工作需要用vue,所以最近接触最多的也是vue,因为之前一直在用react,所以对于vue上手还是很快的.我也尽量找一些他们两个的异同点,除了多了一些辅助用的方法以外,最大的不同应该是对于组件间 ...
- [CLR via C#]21. 自动内存管理(垃圾回收机制)
目录 理解垃圾回收平台的基本工作原理 垃圾回收算法 垃圾回收与调试 使用终结操作来释放本地资源 对托管资源使用终结操作 是什么导致Finalize方法被调用 终结操作揭秘 Dispose模式:强制对象 ...
- Android软键盘的隐藏显示、事件监听的代码
把开发过程中重要的一些内容片段做个珍藏,如下资料是关于Android软键盘的隐藏显示.事件监听的内容,应该是对小伙伴们有所用途. public class ResizeLayout extends L ...
- CLR VIA C#事件
事件是类型的一个成员,用来在事情发生的时候通知注册了该事件的成员. 事件和观察者模式十分的相似,所以事件应该提供如下几种能力 1.能让对象的方法登记对他的关注 2.能让对象的方法取消对他的关注 3.能 ...
- js闭包(函数内部嵌套一个匿名函数:这个匿名函数可将所在函数的局部变量常驻内存)
js闭包(函数内部嵌套一个匿名函数:这个匿名函数可将所在函数的局部变量常驻内存) 一.总结 1.闭包:就是在一个函数内部嵌套一个匿名函数,这个匿名函数可以访问这个函数的变量. 二.要点 闭包 闭包的相 ...
- 一个字典通过dictionaryWithDictionary 他们的内存指针是不同的
一个字典通过dictionaryWithDictionary 他们的内存指针是不同的 来自为知笔记(Wiz)
- 有一个字典对象,d = {'a':1,'b':2},请用尽量简洁的代码将d转换成{1: 'a', 2: 'b'}
题目:有一个字典对象,d = {'a':1,'b':2},请用尽量简洁的代码将d转换成{1: 'a', 2: 'b'} 第一种方法: d = {'a': 1, 'b': 2}d = {value: k ...
- Python把两个列表合成一个字典
简单粗暴上代码 A= [] B = [] C= dict(map(lambda x,y:[x,y],A,B)) 酱紫,就合成了一个字典
随机推荐
- LA2572 Viva Confetti
题意 PDF 分析 两两圆求交点,对每个圆弧按半径抖动. 时间复杂度\(O(T n^2)\) 代码 #include<iostream> #include<cstdio> #i ...
- openfaas cli 安装
1. 安装脚本 curl -sL https://cli.get-faas.com/ | sudo sh 备注安装完成之后如果没有 faas-cli 可以下载脚本,手工执行 2. 使用二进制 ...
- XMemcached使用经历
XMemcached就是Memcached的java客户端之一,目前项目里用到了.据说它比起其他的java客户端从性能上要好一点,实现方式是NIO的.先看怎么实例化出来一个Memcached客户端吧: ...
- Java 编码规范
package(包) 包名的命名规范:1.小写 2.至少有一层目录 3.域名倒置书写 package baidu; package com.baidu.www; Class(类)-----大驼峰法 类 ...
- sublime 工具
http://blog.csdn.net/admin_yi/article/details/53608965
- lua语法基本
lua的下载 http://luabinaries.sourceforge.net/点击所要下载的版本比如我下的是5.3.3https://sourceforge.net/projects/luabi ...
- 分布式缓存系统 Memcached 内存管理机制
在前面slab数据存储部分分析了Memecached中记录数据的具体存储机制,从中可以看到所采用的内存管理机制——slab内存管理,这也正是linux所采用的内存高效管理机制,对于Memchached ...
- Ehcache/Redis/Tair缓存性能对比[转载]
FW : http://xulingbo.net/?p=434 版权归许令波所有.此处只是一个转载. 后面介绍的不同方式都有测试数据,这些测试数据都是在同一的测试环境下得出的测试结果: 测试机器的配置 ...
- 1111 Online Map
题意:给定一个图,以及起点和终点,需要我们计算两条路径.第1条路径:距离最短路径,若不唯一,则选择用时最短的那一条:第2条路径:用时最少路径,若不唯一,选择经过结点数最少的那一条. 思路:两次Dijk ...
- python' s fifth day for me dict
字典 dict : key--vlaue 储存大量的数据,而且是关系型数据,查询速度快(二分查询) 数据类型分类: 可变数据类型(不可哈希):list(列表) , dict(字典), set(集合) ...