最近有時(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í)行完畢返回值
}