淺談C#中的委托、事件與異步
從剛接觸c#編程到現(xiàn)在,差不多快有一年的時(shí)間了。在學(xué)習(xí)過(guò)程中,有很多地方始終似是而非,直到最近才弄明白。
本文將先介紹用法,后評(píng)斷功能。
一、委托
基本用法:
1.聲明一個(gè)委托類(lèi)型。委托就像是‘類(lèi)'一樣,聲明了一種委托之后就可以創(chuàng)建多個(gè)具有此種特征的委托。(特征,指的是返回值、參數(shù)類(lèi)型)
public delegate void SomeKindOfDelegate(string result);
2.創(chuàng)建一個(gè)在1中創(chuàng)建的委托類(lèi)型的委托。
public SomeKindOfDelegate aDelegate;
3.為2中創(chuàng)建的具體的委托添加響應(yīng)函數(shù)。響應(yīng)函數(shù)必須符合1中的‘特征'。
aDelegate +=new SomeKindOfDelegate(aFunctionThatJustForDelegate); private void aFunctionThatJustForDelegate(string result) { MessageBox.Show(result); }
4.完成以上三步之后,就可以使用Invoke來(lái)對(duì)委托進(jìn)行調(diào)用了。Invoke可以選擇調(diào)用的目標(biāo)函數(shù),調(diào)用優(yōu)先級(jí),以及調(diào)用的參數(shù)。
aDelegate.BeginInvoke("Hello~I'm being invoked!", null, null);
上面是基本用法,除了這種基本用法之外,還可以結(jié)合var、匿名委托、lambda委托等方法。
完整代碼:
namespace wtfIsDelegate { public delegate void SomeKindOfDelegate(string result); public partial class Form1 : Form { public event SomeKindOfDelegate aDelegate; public Form1() { InitializeComponent(); aDelegate +=new SomeKindOfDelegate(aFunctionThatJustForDelegate); aDelegate.BeginInvoke("Hello~I'm being invoked!", null, null); } private void btnDelegate_Click(object sender, EventArgs e) { } private void aFunctionThatJustForDelegate(string result) { MessageBox.Show(result); } } }
委托的用處:
委托的優(yōu)點(diǎn),是可以實(shí)現(xiàn)異步(BeginInvoke),還可以在某種需要同時(shí)調(diào)用多個(gè)同參數(shù)、返回值的情況下簡(jiǎn)化代碼。
二、事件
基本用法:
1.定義委托。
public delegate void SomeKindOfDelegate(string result);
2.定義事件。
public event SomeKindOfDelegate aDelegate;
3.為事件添加響應(yīng)函數(shù)。
process.Exited += new EventHandler(CmdProcess_Exited);
4.為事件規(guī)定觸發(fā)(調(diào)用)方式。(【也可以沒(méi)有觸發(fā)方式,直接invoke】)
解說(shuō):
C#里,每一種‘事件Event'大概都對(duì)應(yīng)著其‘事件處理者EventHandler'。比如Process類(lèi)的OutputDataReceived事件對(duì)應(yīng)著DataReceivedEventHandler,對(duì)于非特異性的‘事件',比如PasswordChanged 這種,它們統(tǒng)一都對(duì)應(yīng)著RoutedEventHandler或者EventHandler這種較為通用的‘事件處理者'。然而,‘EventHandler'也只是充當(dāng)了一個(gè)中介的角色,真正觸發(fā)了‘Event'之后要做什么,還需要我們手動(dòng)指定,像這樣:
process.Exited += new EventHandler(CmdProcess_Exited); // 注冊(cè)進(jìn)程結(jié)束事件 。
EventHandler本來(lái)也是委托。比如
public delegate void DataReceivedEventHandler(object sender, DataReceivedEventArgs e);
自定義事件
自定義事件是一種類(lèi)似于委托的方式,
自定義事件某種意義上改變了程序的流程,使得某個(gè)條件的變化由‘不斷查詢(xún)'轉(zhuǎn)變?yōu)椤嗛喤c處理'的關(guān)系。
自定義事件需要有以下幾個(gè)元素:
事件的發(fā)起者,事件的訂閱,以及事件的處理程序。從發(fā)起者到處理程序之間是可以傳參數(shù)的。
一個(gè)事件的‘發(fā)起'可以依賴(lài)于某種系統(tǒng)消息,比如‘OnKeyDown'、‘OnMouseClick'(【我目前還沒(méi)見(jiàn)過(guò)這么寫(xiě)的源碼】),也可以在某個(gè)條件達(dá)成時(shí)(比如兩次輸入了同樣的字符)自行調(diào)用(其實(shí)收到系統(tǒng)消息也算是‘條件達(dá)成')。【更多的event是這么寫(xiě)出來(lái)的】
有些事件,并沒(méi)有明顯的‘發(fā)起者'。
委托和事件是啥關(guān)系
委托和自定義事件的使用方式十分十分類(lèi)似。event 只有類(lèi)的內(nèi)部可以 Invoke,delegate的話,在哪都可以Invoke。調(diào)用的方式貌似也略有區(qū)別(傳參方式)
由于調(diào)用方式和傳參的差異,event顯得更保守/穩(wěn)定一些。event也更容易從‘理解'上更容易接受。
delegate貌似更多的用于進(jìn)行異步(begin invoke)。而event則更多的用來(lái)做自定義事件。
委托和異步是啥關(guān)系
異步是委托可以實(shí)現(xiàn)的一種功能(或者叫做‘現(xiàn)象'也可以) 異步可以由很多種其他方式體現(xiàn),比如多線程(thread,threadpool,task等等)。
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持我們!
您可能感興趣的文章
- 01-10C#中查找Dictionary中的重復(fù)值的方法
- 01-10C#將圖片存放到SQL SERVER數(shù)據(jù)庫(kù)中的方法
- 01-10關(guān)于nancy中的身份驗(yàn)證
- 01-10C#中的事務(wù)用法實(shí)例分析
- 01-10C#實(shí)現(xiàn)讀取DataSet數(shù)據(jù)并顯示在ListView控件中的方法
- 01-10C#中的正則表達(dá)式介紹
- 01-10C#開(kāi)發(fā)中的垃圾回收機(jī)制簡(jiǎn)析
- 01-10C#語(yǔ)言中的修飾符匯總
- 01-10C#中的 == 和equals()區(qū)別淺析
- 01-10C#基于委托實(shí)現(xiàn)多線程之間操作的方法


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開(kāi)的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫(xiě)Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法