.NET基础扩展系列-事件的实现原理

来源:未知 责任编辑:责任编辑 发表时间:2015-03-01 01:48 点击:

CLR VIA C#这本书中, 写到了事件的实现原理, CLR是使用委托字段来实现事件的:
// 1. A PRIVATE delegate field that is initialized to null
static EventHandler<EventArgs> NewMail = null;

// 2. A PUBLIC add_Xxx method (where Xxx is the Event name)
// Allows methods to register interest in the event.
static void add_NewMail(EventHandler<EventArgs> value)
{
    // The loop and the call to CompareExchange is all just a fancy way
    // of adding a delegate to the event in a thread-safe way
    EventHandler<EventArgs> prevHandler;
    EventHandler<EventArgs> tmp = NewMail;
    do
    {
        prevHandler = tmp;
        EventHandler<EventArgs> newHandler = (EventHandler<EventArgs>)Delegate.Combine(prevHandler, value);
        tmp = Interlocked.CompareExchange<EventHandler<EventArgs>>(ref NewMail, newHandler, prevHandler);
    } while (tmp != prevHandler);
}


// 3. A PUBLIC remove_Xxx method (where Xxx is the Event name)
// Allows methods to unregister interest in the event.
public void remove_NewMail(EventHandler<EventArgs> value)
{
    // The loop and the call to CompareExchange is all just a fancy way
    // of removing a delegate from the event in a thread-safe way
    EventHandler<EventArgs> prevHandler;
    EventHandler<EventArgs> tmp = NewMail;
    do
    {
        prevHandler = tmp;
        EventHandler<EventArgs> newHandler = (EventHandler<EventArgs>)Delegate.Remove(prevHandler, value);
        tmp= Interlocked.CompareExchange<EventHandler<EventArgs>>(ref NewMail, newHandler, prevHandler);
    } while (tmp!= prevHandler);
}
 
但是里面tmp = Interlocked.CompareExchange<EventHandler<EventArgs>>(ref NewMail, newHandler, prevHandler);
这一句是用于赋值的, 为什么不采用Interlocked.Exchange方法直接赋值呢? 而要采取这么迂回的方式, 使用CompareExchange和(newMail != prevHandler)来组合判断.

 
在单线程的情况下, 这两种情况的效果是一样的.
而在用多线程并发的情况下, 就会发现为什么只能用CompareExchange.
 
假设有两个线程A和B, 同时在添加实现响应函数, 也就是调用add_NewMail函数.
 
假设事件NewMail初始化时没有时间响应函数, A需要添加一个FunctionA响应函数, B需要添加一个FunctionB函数.
 
第一步:线程A先开始执行,执行完下面这一句后, 停止执行:EventHandler<EventArgs> newHandler =(EventHandler<EventArgs>)Delegate.Combine(prevHandler, value);

发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码:点击我更换图片
最新评论 更多>>

推荐热点

  • 浅析.NET下XML数据访问新机制
  • asp.net 面试+笔试题目第1/2页
  • C# 邮件地址是否合法的验证
  • asp.net 设置GridView的选中行的实现代码
  • C#高级编程:数据库连接[1]
  • ASP.NET&#160;GridView列表代码示例
  • 经典C++程序1
  • 微软ASP.NET站点部署指南(3):使用Web.Config文件的Transforma
  • 微软ASP.NET站点部署指南(2):部署SQL Server Compact数据库
网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索 - 移动版 - 返回顶部
Copyright © 2008-2013 计算机技术学习交流网. 版权所有

豫ICP备11007008号-1