發(fā)文章
發(fā)文工具
撰寫
網(wǎng)文摘手
文檔
視頻
思維導(dǎo)圖
隨筆
相冊(cè)
原創(chuàng)同步助手
其他工具
圖片轉(zhuǎn)文字
文件清理
AI助手
留言交流
歷史上,Windows API經(jīng)常使用C語言風(fēng)格的函數(shù)指針來創(chuàng)建稱為回調(diào)函數(shù)或簡稱為回調(diào)的實(shí)體。使用回調(diào),碼農(nóng)可以使一個(gè)函數(shù)返回報(bào)告給(即回調(diào))程序中的另一個(gè)函數(shù)。
在.NET Framework里,回調(diào)仍是可能的,它們的功能是由使用更為安全和面向?qū)ο蟮?strong>委托(delegate)來完成的。本質(zhì)上來講,委托是一個(gè)類型安全的對(duì)象,它指向程序中另一個(gè)以后會(huì)被調(diào)用的方法(或多個(gè)方法)。委托類型包含3個(gè)得要的信息:
當(dāng)一個(gè)委托被創(chuàng)建并提供了上述信息后,它可以在運(yùn)行時(shí)動(dòng)態(tài)調(diào)用其指向的方法??梢钥吹?,.NET Framwwork中每個(gè)委托(包括自定義委托)都被自動(dòng)賦予同步或異步訪問方法的能力,可以不用手工創(chuàng)建與管理一個(gè)Thread對(duì)象而直接調(diào)用另一個(gè)輔助執(zhí)行線程上的方法,這大大簡化了編程工作。
使用C#定義委托:假定我們要?jiǎng)?chuàng)建一個(gè)名為BinaryOp的委托,它可以指向任何輸入兩個(gè)整數(shù)返回一個(gè)整數(shù)的方法:
public delegate int BinaryOp(int x,int y);
當(dāng)C#編譯器處理委托類型時(shí),它先自動(dòng)產(chǎn)生一個(gè)派生自System.MulticastDelegaet的密封類。這個(gè)類與它的基類System.Degelate 一起為委托提供必要的基礎(chǔ)設(shè)施,以維護(hù)以后將要調(diào)用方法的列表。
寫著寫著突然沒電,沒保存,比改需求還痛苦,沒辦法,只能重來。
如果我們通過ildasm.exe來查看BinaryOp委托可以看到,生成的BinaryOp類定義了三個(gè)公共方法。Invoke()可能是核心方法,因?yàn)樗挥脕硪酝椒绞秸{(diào)用委托類型維護(hù)的每個(gè)方法。BeginInvoke()和EndInvoke()方法能在第二個(gè)執(zhí)行線程上異步調(diào)用當(dāng)前方法。
編譯器是如何確切知道怎樣定義Invoke()、BeginInvoke()和EndInvoke()方法的呢?欲知后事如何,請(qǐng)看下面代碼:
sealed class BinaryOp:System.MulticastDelegate { public BinaryOp(object target,uint functionAddress); public int Invoke(int x,int y); public IAsyncResult BeginInvoke(int x,int y,AsyncCallback cb,object state); public int EndInvoke(IAsyncResult result); }
初次接觸委托可能會(huì)感覺很難。不要緊,接下來,讓我們看一個(gè)非常簡單的使用BinaryOp委托的示例,我們以前見過,這是一個(gè)名為Simple Delegate的控制臺(tái)應(yīng)用程序項(xiàng)目。
namespace SimpleDelegate { // 委托其實(shí)就相當(dāng)于一個(gè)類型。這里,類型的名字叫BinaryOp public delegate int BinaryOp(int x,int y); class SimpleMath { public static int Add(int x, int y) { return x + y; } public static int Substract(int x, int y) { return x - y; } } class Program { static void Main(string[] args) { // 創(chuàng)建一個(gè)BinaryOp類型的實(shí)例,用靜態(tài)Add方法初始化 BinaryOp d = new BinaryOp(Add); Console.WriteLine(d(10, 10)); Console.ReadLine(); } } }
.net委托是類型安全的。所以如果讀者試圖將一個(gè)不匹配模式的方法傳入委托,將會(huì)收到編譯期錯(cuò)誤。例如,假定SimpleMath類定義了一個(gè)名為SquareNumber()的方法:
public class SimpleMath{ ... public static int SquareNumber(int a) { return a*a; } }
由于BinaryOp委托公可指向帶有兩個(gè)整數(shù)參數(shù)并返回一個(gè)整數(shù)的方法下面這段代碼是非法的,將無法編譯:
//錯(cuò)誤!方法不匹配委托的模式 BinaryOp b2=new BinaryOp(SimpleMath.SquareNumber);
委托對(duì)象
我們?cè)趐rogram類型中創(chuàng)建一個(gè)名為DisplayDegelateInfo()的靜態(tài)方法豐富當(dāng)前的示例。這個(gè)方法將輸出傳入的委托類型所維護(hù)的方法的名稱和定義該方法的類的名稱。通過迭代由GetInvocationList()返回的System.Delegate數(shù)組,調(diào)用每個(gè)對(duì)象的Target和method屬性:
static void DisplayDelegateInfo(Delegate delObj) { foreach(Delegate d in delObj.GetInvocationList()) { Console.WriteLine("Method Name:{0}",d.Method); Console.WriteLine("Type Name:{0}",d.Target); } }
來自: 昵稱10504424 > 《工作》
0條評(píng)論
發(fā)表
請(qǐng)遵守用戶 評(píng)論公約
多線程(一):異步委托
-->//在次線程中調(diào)用Add()IAsyncResult iftAr = b.BeginInvoke(10, 10, null, null);Code-->static void AddComplete(IAsyncResult itfAR){WriteLine("AddComplete() 執(zhí)行在線程on thread {...
關(guān)于委托和事件的使用
/** 題外話,上圖提到的Balsamiq Mockups是一個(gè)很棒的軟件, 可以用來畫UI效果圖, 我喜歡用來畫流程圖(稍顯不如visio方便, 但是閱讀...
C#線程中安全訪問控件(重用委托,避免繁復(fù)的delegate,Invoke)總結(jié)
C#線程中安全訪問控件(重用委托,避免繁復(fù)的delegate,Invoke)總結(jié)。
C#異步調(diào)用四大方法詳解
namespace ConsoleAppAsync { // The delegate must have the same signature as the method // you want to call asynchronously. public delegate string AsyncDelega...
C#委托的異步調(diào)用
public class 異步調(diào)用{ static void Main() { Console.WriteLine("===== 異步調(diào)用 AsyncInvokeTest ====="); AddHandler handler = new AddHandler(加...
C#異步調(diào)用的好處和方法
下面你可以很容易想到,回收分為2種情況:主動(dòng)回收和被動(dòng)回收(當(dāng)然,這是我自己的理解,微軟可不是這么說的),主動(dòng)回收就是,你去監(jiān)視那個(gè)線程,并且等待,當(dāng)異步方法完成了,就把異步線程回收,焦點(diǎn)...
C#異步調(diào)用的應(yīng)用淺析
//參數(shù)dn相當(dāng)于該線程的ID,如果有多個(gè)C#異步調(diào)用線程, //可以都是null,但是絕對(duì)不能一樣,不能是同一個(gè)object,否則異常 IAsyncResult iar = dn.BeginInvoke(1, out i, acb, dn); //去做別的事...
.NET異步編程總結(jié)
WriteLine("主線程"); IAsyncResult result = printDelegate.BeginInvoke("Hello World.", null, null); Console.W...
MSDN
這稱為BeginInvoke,它與異步委托調(diào)用很相似,與委托的明顯區(qū)別在于,該調(diào)用以異步方式在線程池的某個(gè)線程上運(yùn)行,然而在此處,它以異步方式在 UI線程上運(yùn)行。它可從任何線程讀取,如果調(diào)用線程是 UI線...
微信掃碼,在手機(jī)上查看選中內(nèi)容