青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

xiaoguozi's Blog
Pay it forword - 我并不覺的自豪,我所嘗試的事情都失敗了······習慣原本生活的人不容易改變,就算現狀很糟,他們也很難改變,在過程中,他們還是放棄了······他們一放棄,大家就都是輸家······讓愛傳出去,很困難,也無法預料,人們需要更細心的觀察別人,要隨時注意才能保護別人,因為他們未必知道自己要什么·····
CLR事件機制建立在委托機制上
class MailManager
    {
        
public class MailEventArgs : EventArgs
        {
            
public MailEventArgs(
                String from,
                String to,
                String subject,
                String body)
            {
                
this.from = from;
                
this.to = to;
                
this.subject = subject;
                
this.body = body;
            }
            
public readonly String from, to, subject, body;
        }
        
public delegate void MailEventHandler(Object sender, MailEventArgs e);
        
public event MailEventHandler MailMsg;
        
protected virtual void OnMailMsg(MailEventArgs e)
        {
            
if (MailMsg != null)
            {
                MailMsg(
this, e);
            }
        }
        
public virtual void SimulateArrivingMsg(String from, String to, String subject, String body)
        {
            MailEventArgs e 
= new MailEventArgs(from, to, subject, body);
            OnMailMsg(e);
        }
    }
以上是一個事件類型定義,簡單步驟:
1.定義一個類型,保存所有傳遞參數。
.net框架規定所有的信息類型繼承于EventArgs,類型名稱以EventArgs結束,EventArgs原型如下:
[Serializable]
public class EventArgs
{
    public static readonly EventArgs Empty = new EventArgs();
    public EventArgs(){};
}
只有一個靜態的Empty成員,因為事件中有些不需要額外的參數信息,所以只要提供EventArgs.Empty,不需要在構造新的對象
2.定義一個委托類型,指定事件觸發時調用的函數原型
public delegate void MailEventHandler(Object sender, MailEventArgs e);
如果事件中并沒有額外的傳遞信息,則可以使用System.EventHandler,原型為
public delegate void EventHandler(Object sender,EventArgs e);
3.定義一個事件成員
public event MailEventHandler MailMsg;
4.定義受保護的虛方法,通知事件登記對象
protected virtual void OnMailMsg(MailEventArgs e);
5.定義驅動事件方法
public virtual void SimulateArrivingMsg(String from, String to, String subject, String body);

深入理解事件
當編譯器遇到
public event MailEventHandler MailMsg;
會產生3個構造,一個私有委托類型,及add和remove方法
private MailEventHandler MailMsg;
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public virtual void add_MailMsg(MailEventHandler handler)
{
     MailMsg = (MailEventHandler)Delegate.Combine(MailMsg, handler);
}
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public virtual void remove_MailMsg(MailEventHandler handler)
{
     MailMsg = (MailEventHandler)Delegate.Remove(MailMsg, handler);
}
通過MailMsg內_prev字段可以將添加的注冊對象保存

偵聽事件
class Fax
    {
        public Fax(MailManager mm)
        {
            mm.MailMsg += new MailManager.MailEventHandler(FaxMsg);
        }
        private void FaxMsg(Object sender, MailManager.MailEventArgs e)
        {

        }
        public void UnRegister(MailManager mm)
        {
            MailManager.MailEventHandler callback = new MailManager.MailEventHandler(FaxMsg);
            mm.MailMsg -= callback;
        }
    }

注意,當一個對象仍然登記有另外一個對象的事件,該對象就不可能對垃圾回收,如果我們類實現了IDisposable接口,那我們應該在
Dispose理注銷所有登記事件

顯示控制事件注冊
private MailEventHandler mailMsgEventHandlerDelegate;
        public event MailEventHandler MailMsg
        {
            add
            {
                mailMsgEventHandlerDelegate =(MailEventHandler)Delegate.Combine(mailMsgEventHandlerDelegate, value);
            }
            remove
            {
                mailMsgEventHandlerDelegate = (MailEventHandler)Delegate.Remove(mailMsgEventHandlerDelegate, value);
            }
        }
        protected virtual void OnMailMsg(MailEventArgs e)
        {
            if (MailMsg != null)
            {
                mailMsgEventHandlerDelegate(this, e);
            }
        }

來代替
public event MailEventHandler MailMsg;定義

當一個類型中含有多個事件時,由于每個事件事例聲明都將產生委托字段,所以推薦
不要提供公共的事件成員變量,使用事件訪問器替換這些變量

class EventHandlerSet:IDisposable
    {
        private Hashtable events = new Hashtable();
        public virtual Delegate this[Object eventKey]
        {
            get
            {
                return (Delegate)events[eventKey];
            }
            set
            {
                events[eventKey] = value;
            }
        }
        public virtual void AddHandler(Object eventKey,Delegate handler)
        {
            events[eventKey] = Delegate.Combine((Delegate)events[eventKey], handler);
        }
        public virtual void RevHandler(Object eventKey, Delegate handler)
        {
            events[eventKey] = Delegate.Remove((Delegate)events[eventKey], handler);
        }
        public virtual void Fire(Object eventKey, Object sender, EventArgs e)
        {
            Delegate d = (Delegate)events[eventKey];
            if (d != null)
                d.DynamicInvoke(new Object[]{sender,e});
        }
        public void Dispose()
        {
            events = null;
        }
        public static EventHandlerSet Synchronized(EventHandlerSet eventHandlerSet)
        {
            if (eventHandlerSet == null)
                throw new ArgumentNullException("eventHandlerSet");
            return new SynchronizedEventHandlerSet(eventHandlerSet);
        }
        public class SynchronizedEventHandlerSet : EventHandlerSet
        {
            private EventHandlerSet eventHandlerSet;
            public SynchronizedEventHandlerSet(EventHandlerSet eventHandlerSet)
            {
                this.eventHandlerSet = eventHandlerSet;
                Dispose();
            }
            public override Delegate this[object eventKey]
            {
                [MethodImpl(MethodImplOptions.Synchronized)]
                get
                {
                    return eventHandlerSet[eventKey];
                }
                set
                {
                    eventHandlerSet[eventKey] = value;
                }
            }
            [MethodImpl(MethodImplOptions.Synchronized)]
            public override void AddHandler(object eventKey, Delegate handler)
            {
                eventHandlerSet.AddHandler(eventKey, handler);
            }
            [MethodImpl(MethodImplOptions.Synchronized)]
            public override void RevHandler(object eventKey, Delegate handler)
            {
                eventHandlerSet.RevHandler(eventKey, handler);
            }
            [MethodImpl(MethodImplOptions.Synchronized)]
            public override void Fire(object eventKey, object sender, EventArgs e)
            {
                eventHandlerSet.Fire(eventKey, sender, e);
            }
        }
    }
    class TypeWithLotsEvents
    {
        protected EventHandlerSet eventSet = EventHandlerSet.Synchronized(new EventHandlerSet());
        protected static readonly Object fooEventKey = new Object();
        public class FooEventArgs : EventArgs { };
        public delegate void FooEventHandler(Object sender, FooEventArgs e);
        public event FooEventHandler Foo
        {
            add
            {
                eventSet.AddHandler(fooEventKey, value);
            }
            remove
            {
                eventSet.AddHandler(fooEventKey, value);
            }
        }
        protected virtual void OnFoo(FooEventArgs e)
        {
            eventSet.Fire(fooEventKey, this, e);
        }
        public void SimulateFoo()
        {
            OnFoo(new FooEventArgs());
        }

    }
以上是microsoft .net 框架設計一個example,如果設計該種事件類型,其中給出了EventHandlerSet的實現,
.net框架中也有類似的事件 EventHandlerList,但是訪問效率和線程同步有缺陷,所以有需要我們自己提供
EventHandlerSet實現.詳情請參考microsoft .net 框架設計

posted on 2010-09-30 14:17 小果子 閱讀(449) 評論(0)  編輯 收藏 引用 所屬分類: .Net

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            99精品热视频| 欧美综合77777色婷婷| 中文精品视频| 久久大逼视频| 午夜精品一区二区三区四区| 免费成人av在线看| 国产精品嫩草99a| 亚洲国产高清自拍| 欧美一级淫片aaaaaaa视频| 欧美国产1区2区| 亚洲一区二区黄| 欧美高清视频在线播放| 国产一区二区三区久久久久久久久 | 久久久久久亚洲综合影院红桃| 亚洲高清资源| 久久精品99国产精品日本 | 亚洲午夜精品视频| 亚洲第一页中文字幕| 美女主播一区| 亚洲亚洲精品三区日韩精品在线视频| 中国成人黄色视屏| 欧美日韩精品在线视频| 亚洲黄色性网站| 久久只精品国产| 午夜一区二区三区在线观看| 狠狠色丁香婷综合久久| 欧美在线不卡| 亚洲免费人成在线视频观看| 国产精品扒开腿做爽爽爽视频| 日韩亚洲欧美中文三级| 亚洲高清av| 国产精品卡一卡二卡三| 欧美aaa级| 免费欧美在线| 亚洲伦理自拍| 亚洲精品一区二区三区99| 蜜桃av噜噜一区二区三区| 亚洲在线免费| 亚洲午夜激情免费视频| 国产精品久久久久久久久久三级 | 亚洲人成亚洲人成在线观看| 欧美成ee人免费视频| 欧美日韩国产成人在线观看| 久久久久中文| 国产精品一区在线观看你懂的| 亚洲欧美日韩精品| 亚洲综合视频在线| 一区二区欧美在线| 亚洲欧美国产一区二区三区| 亚洲日韩欧美视频| 一区二区欧美精品| 国产亚洲一区在线| 亚洲午夜久久久| 亚洲精品视频免费观看| 久久久蜜桃一区二区人| 亚洲免费观看| 免费日韩成人| 欧美岛国在线观看| 在线看片欧美| 亚洲免费观看| 国产午夜精品理论片a级大结局| 老**午夜毛片一区二区三区| 欧美国产综合一区二区| 欧美.com| 亚洲第一福利视频| 久久精品日韩| 亚洲一区免费视频| 欧美日韩日本国产亚洲在线| 久久国产夜色精品鲁鲁99| 国产精品免费网站| 亚洲视频www| 欧美亚洲三区| 国产一区二区三区在线观看免费视频 | 欧美一区在线视频| 日韩视频免费在线| 欧美高清你懂得| 亚洲国产中文字幕在线观看| 国产欧美一区二区在线观看| 亚洲国产成人久久| 亚洲精品欧美日韩| 欧美日韩午夜剧场| 中文亚洲视频在线| 欧美一区二区精品| 国产欧美一区二区三区国产幕精品| 这里只有精品丝袜| 欧美一级成年大片在线观看| 国产精品乱人伦中文| 亚洲综合色视频| 久久影视精品| 亚洲人成精品久久久久| 欧美精品在线一区| 欧美暴力喷水在线| 日韩一区二区精品| 国产精品高潮久久| 亚洲精品国精品久久99热| 国模吧视频一区| 亚洲在线免费| 免费91麻豆精品国产自产在线观看 | 欧美电影免费观看高清完整版| 亚洲第一精品福利| 欧美日韩天堂| 久久精品国产亚洲精品| 亚洲永久免费精品| 国产日韩一区二区| 欧美xart系列高清| 欧美黄色视屏| 亚洲国产经典视频| 欧美色图一区二区三区| 亚洲美女区一区| 久久黄色小说| 日韩一本二本av| 国产日韩欧美视频| 欧美大秀在线观看| 亚洲欧美日韩综合国产aⅴ| 欧美中文字幕视频| 亚洲精品在线一区二区| 国产乱子伦一区二区三区国色天香| 久久一二三四| 亚洲福利视频免费观看| 午夜视频一区| 国内久久婷婷综合| 欧美日韩美女| 乱中年女人伦av一区二区| 亚洲一区二区成人在线观看| 亚洲黄色av一区| 麻豆freexxxx性91精品| 午夜精品福利一区二区蜜股av| 亚洲激情专区| 在线不卡免费欧美| 欧美激情va永久在线播放| 欧美一区网站| 亚洲国产日韩一区| 免费国产自线拍一欧美视频| 欧美一区永久视频免费观看| 一区二区毛片| 亚洲精品乱码久久久久久蜜桃91| 国产一区二区三区四区五区美女| 国产精品久久久久久久免费软件| 欧美福利电影网| 欧美高清日韩| 欧美成年人视频网站| 玖玖综合伊人| 一区二区福利| 亚洲九九精品| 日韩午夜在线视频| 亚洲另类在线一区| 亚洲精品少妇30p| 亚洲精品欧美专区| 亚洲精品资源| 日韩视频不卡中文| 中文精品视频| 亚洲线精品一区二区三区八戒| 一本一本久久a久久精品综合妖精| 亚洲精品你懂的| 欧美韩国日本综合| 亚洲福利视频在线| 日韩视频在线观看一区二区| 亚洲美女毛片| 亚洲视频在线观看免费| 亚洲永久精品大片| 欧美在线视频一区二区| 久久久久国产一区二区三区四区| 久久久精品国产一区二区三区 | 午夜精品视频在线观看| 久久精品99无色码中文字幕 | 午夜精品久久久99热福利| 欧美在线黄色| 免费在线亚洲欧美| 欧美日韩在线播| 国产精品丝袜久久久久久app| 欧美成人精品不卡视频在线观看| 欧美成人亚洲成人| 欧美日韩一区二区视频在线| 国产欧美日韩视频一区二区| 激情婷婷久久| 黄色亚洲精品| 99热免费精品在线观看| 欧美一级一区| 欧美激情一区二区三区成人| 99精品视频免费观看视频| 午夜久久久久| 欧美精品一区二区三| 国产精品一区二区黑丝| 91久久国产综合久久蜜月精品 | 99re热这里只有精品视频| 欧美在线观看视频一区二区三区| 久久一综合视频| 99视频精品在线| 久久久精品2019中文字幕神马| 欧美激情亚洲精品| 欧美劲爆第一页| 国产日韩一区二区三区在线| 亚洲三级免费电影| 久久er精品视频| 亚洲精品一二区| 久久久久久久精| 国产精品腿扒开做爽爽爽挤奶网站| 亚洲第一毛片| 欧美在线观看视频| 日韩亚洲国产精品|