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

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 小果子 閱讀(446) 評論(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>
            一本一本久久a久久精品综合麻豆| 亚洲网站视频福利| 亚洲国产三级| 亚洲女性裸体视频| 国产欧美精品在线播放| 亚洲一区制服诱惑| 午夜宅男欧美| 亚洲高清免费视频| 欧美日韩成人网| 一本久道久久综合狠狠爱| 亚洲二区在线观看| 久久综合电影一区| 欧美一级专区免费大片| 亚洲夜间福利| 久久av一区二区三区亚洲| 国产毛片久久| 久久久久久91香蕉国产| 久久亚洲一区二区| 欧美日韩国产一区| 亚洲国产毛片完整版| 亚洲欧洲三级电影| 久久超碰97中文字幕| 亚洲天堂成人| 欧美日韩网站| 亚洲精品乱码久久久久久按摩观| 国产亚洲福利| 亚洲国产视频直播| 久久综合久久美利坚合众国| 欧美自拍偷拍| 国内精品久久久久久久影视蜜臀| 99精品国产在热久久下载| 亚洲视频精品| 亚洲午夜精品久久| 欧美日韩在线观看视频| 精品不卡一区| 中文一区二区| 免费在线播放第一区高清av| av成人免费在线观看| 国产目拍亚洲精品99久久精品| 久久精品国产清高在天天线| 亚洲精品永久免费精品| 久久久噜噜噜久久中文字免| 在线观看中文字幕亚洲| 亚洲色图自拍| 在线看片第一页欧美| 在线亚洲国产精品网站| 国内不卡一区二区三区| 久久国产免费| 国产精品嫩草99av在线| 亚洲宅男天堂在线观看无病毒| 亚洲精品国产精品国自产观看浪潮 | 国产日韩欧美日韩| 99在线热播精品免费99热| 欧美激情视频一区二区三区不卡| 欧美在线视频观看| 国产一区二区三区四区老人| 久久成人国产| 女女同性女同一区二区三区91| 在线一区视频| 欧美成人日本| 国产嫩草影院久久久久| 嫩草影视亚洲| 伊人婷婷欧美激情| 欧美激情a∨在线视频播放| 久久精品国产第一区二区三区最新章节| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 国产偷国产偷亚洲高清97cao| 亚洲调教视频在线观看| 久久久久久91香蕉国产| 欧美日韩ab片| 久久不见久久见免费视频1| 欧美日韩国产小视频在线观看| 久久久999精品免费| 欧美日韩一区在线视频| 亚洲人成人77777线观看| 国产亚洲高清视频| 在线视频中文亚洲| 亚洲午夜电影在线观看| 欧美日韩综合久久| 最新成人av网站| 国产婷婷色一区二区三区四区| 一区二区三区欧美在线观看| 欧美一区二区在线视频| 亚洲破处大片| 亚洲国产第一页| 欧美日韩综合另类| 校园春色综合网| 一本久久综合亚洲鲁鲁五月天| 亚洲精品无人区| 国产精品揄拍500视频| 久久夜色精品国产亚洲aⅴ| 欧美国产日产韩国视频| 亚洲视频第一页| 亚洲美女在线一区| 激情欧美一区二区| 欧美日本高清视频| 国产精品狠色婷| 午夜亚洲精品| 久久久999精品视频| 亚洲一区二区三区影院| 蜜桃伊人久久| 欧美一区二区免费| 一区二区高清在线| 中文一区在线| 亚洲视频在线观看| 久久久www成人免费毛片麻豆| 亚洲靠逼com| 精品999久久久| 久久国产欧美精品| 亚洲欧美成人一区二区在线电影| 免费在线国产精品| 亚洲欧美一区二区原创| 国产一区二区久久久| 国产精品一区二区黑丝| 国产精品久久国产愉拍| 国产亚洲一级| 国产亚洲欧美日韩一区二区| 国产一区在线看| 欧美日本簧片| 国产欧美日韩免费| 国产欧美精品在线播放| 国产精品制服诱惑| 国模私拍一区二区三区| 亚洲人成网站在线观看播放| 在线亚洲免费视频| 亚洲日本成人女熟在线观看| 亚洲欧美日本视频在线观看| 久久精品一区四区| 亚洲激情av| 亚洲砖区区免费| 免费高清在线一区| 欧美日韩一卡二卡| 亚洲欧洲一区二区三区| 香蕉尹人综合在线观看| 亚洲精品一区二区三区福利| 欧美专区在线观看一区| 国产精品高潮呻吟久久| 欧美午夜精品久久久| 午夜精品一区二区三区在线播放| 一本色道久久综合精品竹菊| 欧美一级电影久久| 亚洲激情视频在线观看| 可以免费看不卡的av网站| 欧美日韩卡一卡二| 亚洲国产日本| 开心色5月久久精品| 亚洲素人在线| 国产精品久久久久一区| 亚洲欧洲精品一区| 亚洲精品欧美极品| 亚洲第一区在线观看| 亚洲在线视频一区| 欧美日韩国产首页在线观看| 亚洲一区二区在线观看视频| 西西人体一区二区| 国产欧美va欧美va香蕉在| 欧美在线播放一区| 亚洲女女做受ⅹxx高潮| 亚洲国产一区二区三区高清| 亚洲淫片在线视频| 亚洲精品国产欧美| 国产精品入口福利| 久久精品二区三区| 欧美精品一区二区三区很污很色的| 一本大道久久精品懂色aⅴ| 99日韩精品| 亚洲日本久久| 性欧美video另类hd性玩具| 亚洲春色另类小说| 欧美激情国产日韩精品一区18| 你懂的国产精品| 亚洲日本理论电影| 这里只有视频精品| 亚洲精品乱码视频| 小黄鸭精品密入口导航| 一区二区免费在线视频| 久久成人这里只有精品| 亚洲综合清纯丝袜自拍| 亚欧成人在线| 午夜免费在线观看精品视频| 蜜臀av性久久久久蜜臀aⅴ| 一道本一区二区| 欧美巨乳在线| 美女主播一区| 91久久黄色| 亚洲欧美日韩精品久久久| 亚洲视频免费看| 国产精品久久久爽爽爽麻豆色哟哟| 欧美aaaaaaaa牛牛影院| 国产一区香蕉久久| 亚洲综合首页| 亚洲一区二区三区高清不卡| 欧美日韩一区在线| 亚洲视频在线一区观看| 久久久久久久久岛国免费| 国产精品久久久久久久久| 亚洲素人在线| 国产日韩一区二区| 欧美视频国产精品| 免播放器亚洲一区|