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

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>
            亚洲一区网站| 久久99在线观看| 国产精品丝袜久久久久久app| 麻豆成人在线播放| 老鸭窝亚洲一区二区三区| 久久―日本道色综合久久| 久久久久久自在自线| 久久免费视频网站| 欧美大学生性色视频| 欧美日韩一区二区欧美激情 | 在线观看视频日韩| 亚洲第一页中文字幕| 亚洲精品少妇30p| 亚洲视频在线二区| 久久九九热re6这里有精品| 美女久久网站| 欧美国产免费| 亚洲精品综合| 亚洲资源av| 久久久久久自在自线| 欧美精品综合| 国产视频久久| 99re热这里只有精品视频| 性做久久久久久免费观看欧美| 久久一区免费| 99精品国产在热久久婷婷| 欧美一区二区在线免费观看| 欧美成人午夜| 国产私拍一区| av成人免费在线| 久久影院亚洲| 亚洲午夜一区| 欧美激情1区2区3区| 禁久久精品乱码| 亚洲专区免费| 亚洲欧洲一区二区三区| 亚洲欧美综合| 欧美成人精品h版在线观看| 国产精品资源| 一区二区毛片| 欧美激情视频一区二区三区在线播放| 亚洲午夜在线| 欧美精品自拍| 亚洲日韩第九十九页| 久久人91精品久久久久久不卡| 一区二区日本视频| 欧美日韩a区| 亚洲国产精品va| 久久久五月婷婷| 午夜视频久久久久久| 欧美系列电影免费观看| 亚洲精选一区| 亚洲国产欧美国产综合一区| 久久久久久有精品国产| 国外视频精品毛片| 久久免费一区| 久久国产婷婷国产香蕉| 国产一区二区欧美| 久久精品91| 久久国产夜色精品鲁鲁99| 国产性猛交xxxx免费看久久| 欧美一区二区日韩| 西瓜成人精品人成网站| 国产精品男女猛烈高潮激情| 亚洲香蕉伊综合在人在线视看| 亚洲欧洲精品天堂一级| 欧美区一区二| 中日韩高清电影网| 日韩视频―中文字幕| 欧美日韩日韩| 亚洲图片欧洲图片日韩av| 99riav1国产精品视频| 欧美日韩中文字幕在线| 亚洲欧美日韩高清| 欧美一区二区三区视频免费| 日韩视频在线免费观看| 亚洲精品一区二区三区av| 欧美交受高潮1| 夜夜嗨av一区二区三区免费区| 亚洲精品视频在线播放| 欧美视频在线播放| 久久国产福利| 久久视频一区二区| 一区二区黄色| 午夜国产不卡在线观看视频| 国产亚洲欧美一级| 欧美国产日本| 欧美肉体xxxx裸体137大胆| 性色av一区二区三区红粉影视| 欧美一区综合| 最近中文字幕mv在线一区二区三区四区| 亚洲国产成人av好男人在线观看| 欧美日本在线看| 午夜久久tv| 免费成人av在线看| 午夜精品一区二区三区四区 | 久久精品久久99精品久久| 久久久久久亚洲精品不卡4k岛国| 亚洲国产二区| 亚洲视频www| 精品91在线| 在线视频日韩| 亚洲国产欧美日韩| 午夜精品久久久| 亚洲理伦电影| 欧美一区二区啪啪| 一区二区三区日韩欧美精品| 欧美中文字幕在线观看| 亚洲天堂激情| 久久在线视频| 欧美一区二区三区视频免费| 欧美mv日韩mv国产网站app| 欧美亚洲尤物久久| 欧美日韩国内自拍| 欧美成年人在线观看| 国产精品视频免费| 日韩亚洲欧美综合| 亚洲国产视频直播| 久久国产日韩| 亚洲欧美日韩一区二区三区在线| 欧美成人xxx| 久久夜色精品国产亚洲aⅴ | 国产精品国产成人国产三级| 亚洲第一综合天堂另类专| 国产一区二区三区免费不卡 | 亚洲日本在线视频观看| 久久爱另类一区二区小说| 欧美一级片一区| 国产精品jvid在线观看蜜臀| 亚洲精品免费看| 亚洲精选中文字幕| 免费毛片一区二区三区久久久| 久久久久99精品国产片| 国产乱码精品一区二区三| 国产精品久久久久久久第一福利| 亚洲国内在线| 久久久精品国产免费观看同学| 欧美一二三视频| 国产精品vip| 中文国产亚洲喷潮| 午夜精品99久久免费| 国产精品不卡在线| 一区二区免费在线观看| 一区二区三区日韩| 国产精品成av人在线视午夜片| 洋洋av久久久久久久一区| 亚洲私人影院在线观看| 欧美性理论片在线观看片免费| 亚洲美女在线一区| 亚洲免费在线视频一区 二区| 国产精品v欧美精品v日韩精品| 一区二区三区蜜桃网| 亚洲欧洲av一区二区| 国产无遮挡一区二区三区毛片日本| 午夜一区二区三视频在线观看| 久久精品视频亚洲| 激情综合自拍| 麻豆精品在线视频| 亚洲经典自拍| 亚洲欧美网站| 国内精品久久久久影院优| 久久综合狠狠综合久久综合88| 欧美暴力喷水在线| 一本久久a久久精品亚洲| 国产精品h在线观看| 亚洲欧美在线观看| 美女任你摸久久| 在线亚洲观看| 国产色视频一区| 欧美成人第一页| 亚洲性线免费观看视频成熟| 久久午夜影视| 中文精品视频| 国内精品久久久久影院优| 欧美精品999| 亚洲欧美自拍偷拍| 亚洲精品乱码久久久久久日本蜜臀| 亚洲欧美日韩一区二区三区在线| 狠狠入ady亚洲精品| 欧美日韩国产大片| 久久久国产91| 亚洲影院免费| 亚洲风情在线资源站| 欧美在线一区二区| 亚洲视频欧洲视频| 亚洲黑丝在线| 国产欧美一区二区精品秋霞影院 | 在线成人黄色| 欧美婷婷久久| 欧美大片va欧美在线播放| 欧美专区第一页| 亚洲午夜国产成人av电影男同| 欧美成人久久| 久久精品国产欧美亚洲人人爽| 日韩一级免费观看| 在线免费观看视频一区| 国产日韩在线一区二区三区| 国产精品va在线| 欧美屁股在线| 欧美高清成人|