C# 委托(delegate)的基本使用和異步調(diào)用

最近有時(shí)間把自己的學(xué)習(xí)和開發(fā)經(jīng)驗(yàn)做一個(gè)整理刻撒,有不對(duì)的地方歡迎討論舶衬。

1.委托

委托是一個(gè)類,用來定義指定的方法類型长赞, 委托類型的變量可以保存相應(yīng)類型的方法晦攒,將方法作為參數(shù)傳遞。一個(gè)方法類型指定了它可以保存的方法的參數(shù)類型和返回值類型得哆。

1.1委托基本使用及使用場(chǎng)景

1.1.1 將方法作為參數(shù)傳遞

比如在定義了一個(gè)統(tǒng)一的刷新頁面處理方法中脯颜,不同的頁面刷新過程中有不同的處理,可以將處理方法作為參數(shù)傳入贩据。

首先定義一個(gè)委托類型栋操,在統(tǒng)一方法中傳入此委托類型

public delegate void specialRefresh(string message); //定義委托類型
public static void FullRefrsh(string message, specialRefresh sR) //傳參
 {
       //...之前操作
        sR(message);
       //...之后操作
 }

在page1中調(diào)用統(tǒng)一的刷新方法

public static void page1()
 {
      xx.FullRefrsh("page1刷新", page1Refresh)闸餐; 
 }
public static void page1Refresh(string mes)
{
       //page1刷新操作
}

1.1.2 多播委托

一個(gè)委托可以存儲(chǔ)多個(gè)方法,使用+=向委托中添加方法讼庇,-=刪除委托中的某個(gè)方法绎巨,使用=直接給委托賦值,會(huì)覆蓋掉之前添加的方法蠕啄。比如在某個(gè)操作中一個(gè)值改變场勤,多個(gè)頁面都需要刷新,此時(shí)一個(gè)一個(gè)調(diào)用每個(gè)頁面的刷新方法是非常麻煩的歼跟,我們可以用委托把每個(gè)方法預(yù)先保存下來和媳,統(tǒng)一調(diào)用。

public delegate void specialRefresh(string message); //定義委托類型
public static specialRefresh sR;
public static void FullRefrsh(string message) 
 {
      sR?.Invoke(message);  //執(zhí)行委托中的所有方法哈街,也可以直接sR(message) 留瞳,但此時(shí)沒有傳入方法會(huì)出錯(cuò)
 }

在頁面中向委托傳入方法

public static void page1()
 {
      xx.sR+=page1Refresh;
 }
public static void page1Refresh(string mes)
{
       //page1刷新操作
}

public static void page2()
 {
      xx.sR+=page2Refresh;
 }
public static void page2Refresh(string mes)
{
       //page2刷新操作
}

1.1.3 Action、Func委托介紹

Action和Func是預(yù)先定義好的系統(tǒng)委托類型骚秦,能滿足大多數(shù)情況下的使用她倘,不用再去自定義委托類型。

Action

Action封裝了沒有返回值的委托作箍,使用方式為Action<參數(shù)>硬梁。

public Action a1; //相當(dāng)于 void ()
public Action<string> a2; //void (string s)
public Action<int,string> a3; //void (int i,string s)

Func

Func封裝了帶返回值的委托,使用方式為Func<參數(shù)>胞得,F(xiàn)unc類型最后一個(gè)參數(shù)為返回值類型荧止,不能不帶參數(shù)。

public Func<string>; //相當(dāng)于 string  ()
public Func<int,string>; //string  (int i)

1.3委托調(diào)用

1.3.1直接調(diào)用

委托可以直接像方法一樣調(diào)用阶剑,需判斷是否為空跃巡,委托中沒有注冊(cè)方法會(huì)出錯(cuò)。

if(sR!=null) sR(message); 

1.3.2 Invoke方法調(diào)用

和直接調(diào)用類似牧愁,可使用素邪?判斷是否為空,為空則不執(zhí)行猪半。

sR?.Invoke(message)娘香;//sR.Invoke(message)

1.3.3 BeginInvoke異步調(diào)用

BeginInvoke和前面兩種方法的不同是它是異步調(diào)用的,使用線程池中的線程執(zhí)行方法办龄。BeginInvoke(...,asyncCallback callback,object object),前面的參數(shù)是方法中的傳入?yún)?shù),可以為0個(gè)到多個(gè),倒數(shù)第二個(gè)參數(shù)為回調(diào)方法淋昭,可傳入一個(gè)在方法異步執(zhí)行完調(diào)用的方法俐填,最后一個(gè)參數(shù)可向回調(diào)方法中傳遞數(shù)據(jù)。

sR.BeginInvoke(message,null,null);   //執(zhí)行完不需要執(zhí)行其他操作可直接調(diào)用

EndInvoke方法獲取返回值

Func<string> fun = fMethod;  //定義一個(gè)string返回值類型的委托翔忽,傳入fMethod方法
IAsyncResult ar=fun.BeginInvoke(null,null); //異步執(zhí)行
//中間執(zhí)行其他操作,如果中間沒有操作直接同步執(zhí)行就可以了英融,不需要用異步方法
 string result = fun.EndInvoke(ar);//從執(zhí)行線程中拿到結(jié)果盏檐,此時(shí)若執(zhí)行沒有結(jié)束會(huì)阻塞當(dāng)前線程直到拿到結(jié)果

回調(diào)

使用回調(diào)方法執(zhí)行完后會(huì)自動(dòng)執(zhí)行回調(diào)方法,可在回調(diào)方法中獲取執(zhí)行結(jié)果進(jìn)行后續(xù)操作

fun.BeginInvoke(callback, "執(zhí)行了fMethod方法"); //異步執(zhí)行并傳入數(shù)據(jù)

static void callback(IAsyncResult asyncResult) //執(zhí)行完畢的回調(diào)方法
{
      AsyncResult result = asyncResult as AsyncResult;
      Func<string> fun = result.AsyncDelegate as Func<string>;
      string data = (string)asyncResult.AsyncState;   //傳入的數(shù)據(jù)
      string  r = fun.EndInvoke(asyncResult);   //方法執(zhí)行完畢返回值
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末驶悟,一起剝皮案震驚了整個(gè)濱河市胡野,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌痕鳍,老刑警劉巖硫豆,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異笼呆,居然都是意外死亡熊响,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門诗赌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汗茄,“玉大人,你說我怎么就攤上這事铭若『樘迹” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵叼屠,是天一觀的道長(zhǎng)瞳腌。 經(jīng)常有香客問我,道長(zhǎng)环鲤,這世上最難降的妖魔是什么纯趋? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮冷离,結(jié)果婚禮上吵冒,老公的妹妹穿的比我還像新娘。我一直安慰自己西剥,他們只是感情好痹栖,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瞭空,像睡著了一般揪阿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咆畏,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天南捂,我揣著相機(jī)與錄音,去河邊找鬼旧找。 笑死溺健,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的钮蛛。 我是一名探鬼主播鞭缭,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼剖膳,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了岭辣?” 一聲冷哼從身側(cè)響起吱晒,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沦童,沒想到半個(gè)月后仑濒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搞动,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年躏精,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹦肿。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡矗烛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出箩溃,到底是詐尸還是另有隱情瞭吃,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布涣旨,位于F島的核電站歪架,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏霹陡。R本人自食惡果不足惜和蚪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烹棉。 院中可真熱鬧攒霹,春花似錦、人聲如沸浆洗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伏社。三九已至抠刺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間摘昌,已是汗流浹背速妖。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留聪黎,地道東北人罕容。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親杀赢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容