<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我們已經知道 C#當中 存在async/await 、BackGroudWorker類以及TPL(任務並行庫)。當然C#還有一些舊的模式來支援非同步程式設計。
delegate long MyDel(int first, int second); class Program { static long Sum(int x, int y) { Console.WriteLine("------Inside Sum@{0}", DateTime.Now.ToString()); Thread.Sleep(2000); return x + y; } static void Main(string[] args) { MyDel del = new MyDel(Sum); Console.WriteLine("Before BeginInvoke---@{0}", DateTime.Now.ToString()); IAsyncResult iar = del.BeginInvoke(3, 5, null, null); Console.WriteLine("After BeginInvoke@{0}", DateTime.Now.ToString()); Console.WriteLine("Doing stuff@{0}", DateTime.Now.ToString()); long result = del.EndInvoke(iar); Console.WriteLine("End Invoke@{0}", DateTime.Now.ToString()); Console.WriteLine("After EndInvoke: {0}", result); Console.ReadKey(); } }
如上程式碼,定義了一個委託 MyDel ,並且在呼叫的時候把Sum方法傳給了它的物件。一般情況下我們呼叫這個委託物件,它就會呼叫他呼叫列表中包含的方法。就想呼叫方法一樣,這是同步完成的。
但是如果委託物件在呼叫列表中只有一個方法(參照方法),它就可以非同步的去執行這個方法。BeginInovke和EndInvoke就是用來做這個事的。我們可以用如下的方式使用:
上面的使用過程就引出的三種模式:
① 我們可以根據上面的程式碼知道,BeginInvoke的引數包含如下兩個部分
②BeginInvoke 會線上程池中找到一個執行緒,讓參照方法執行在該執行緒上
③BeginInvoke 返回給呼叫執行緒一個實現IAsyncResult介面的物件的參照。這個介面參照包含了線上程池執行緒中執行的非同步方法的狀態。可以判斷這個狀態來確定非同步方法是否結束。
// 3和5是參照方法引數,兩個null分別是Callback引數和State引數 // iar是新執行緒的資訊 IAsyncResult iar = del.BeginInvoke(3, 5, null, null);
①他的引數是上面BegionInvoke返回的IAsyncResult介面的參照物件,傳入這個物件是便於EndInvoke去找到參照方法執行的執行緒。並且這個引數置於參數列最後一個。EndInvoke提供了從非同步方法呼叫的所有輸出,包括ref和out引數。如果委託的參照方法有ref和out引數,他們必須包含在EndInvoke的參數列當中
IAsyncResult iar2 = del2.BeginInvoke(3, 5, out res, null, null); del2.EndInvoke(out res, iar2);
②如果執行緒已經退出了,EndInvoke會做如下事情:
③如果EndInovke發現執行緒還在執行中,那麼呼叫執行緒就會停止並等待,直到清理完畢並返回值。
④因為EndInvoke會去清理執行緒資訊,所以BeginInvoke和EndInvoke必須成對使用。
⑤如果非同步方法出現異常,那麼在呼叫EndInvoke的時候會丟擲異常。
上面說BeginInvoke方法返回了一個IAsyncResult介面的參照物件(內部是AsyncResult類的物件),AsyncResult型別表現了非同步方法的狀態。下面是這類的主要組成部分:
//開始執行非同步方法 IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //Do Something 耗時 del2.EndInvoke(iar);
像上面的程式碼,BeginInvoke之後,做了一些事情,然後呼叫EndInvoke來處理結果,這種方式就是等待-直到完成的模式。
輪詢模式中,原始的執行緒發起了非同步的方法呼叫,做一些事情,然後使用IAsyncResult中的IsComplete熟悉來定期檢查開啟的執行緒是否完成。如果未完成就在去做一些其他事情。
delegate long MyDel(int first, int second); class Program { static long Sum(int x, int y) { Console.WriteLine("--Inside Sum@{0}", DateTime.Now.ToString()); Thread.Sleep(200); return x + y; } static void Main(string[] args) { MyDel del = new MyDel(Sum); //開始執行非同步方法 IAsyncResult iar = del.BeginInvoke(3, 5, null, null); //輪詢開始 while (!iar.IsCompleted) { //未完成,執行下面的語句 for (long i = 0; i < 20000000; i++) ; } //執行完成呼叫EndInvoke獲取結果 long result = del.EndInvoke(iar); Console.ReadKey(); } }
前兩種都是主動方式的,原始執行緒一直在監控這新開啟的執行緒。但是回撥是被動的,一旦原始執行緒發起了非同步方法,它就自己管自己了,不在考慮同步。
當非同步方法呼叫結束之後,系統呼叫一個使用者自定義的方法來處理結果,並且呼叫委託的EndInvoke方法。這個使用者自定義的方法就是回撥方法。
上面的BegionInvoke中寫過,他會有兩個引數一個Callback引數和一個State引數.
CallBack引數:是回撥方法的名稱。
State引數:可以是null,或者傳入回撥方法的一個物件的參照。我們可以用IAsyncResult引數的AsyncState屬性來獲取這個物件,引數的型別是object。
回撥方法的簽名和返回型別必須和 AsyncCallback委託型別所描述的形式一致。
兩種方式,構建這個AsyncCallback引數
new AsyncCallback 物件
IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone),null);
直接傳回撥方法的名稱
IAsyncResult iar = del.BeginInvoke(3, 5, CallWhenDone, null);
其中 CallWhenDone 如下:
static void CallWhenDone(IAsyncResult iar) { AsyncResult ar = (AsyncResult)iar; MyDel del = (MyDel)ar.AsyncDelegate; //回撥方法中呼叫了EndInvoke long result = del.EndInvoke(iar); }
上面程式碼中,在回撥中使用了EndInvoke,上文中說到 EndInvoke的呼叫,是委託的呼叫,並且需要傳入一個IAsyncResult的介面物件的參照。
所以想要在回撥方法裡面,呼叫這個EndInvoke,就得拿到兩個東西一個是委託物件、一個是IAsyncResult,由於我們AsyncCallback委託本身就是必須要傳入IAsyncResult 的,所以這個比較容易,剩下的就是委託物件本身了。在AsyncResult類小節裡面我看到,它裡面存著一個 AsyncDelegate(它就是委託物件的參照),還有就是 IAsyncResult介面物件在內部就是AsyncResult類物件。所以才可以像上main的程式碼,通過強制型別轉換得到MyDel的物件。
第二種方法就是如果State引數沒有用處,可以通過State引數,把委託的物件傳過去。
呼叫的地方,最後一個引數傳入del
IAsyncResult iar = del.BeginInvoke(3, 5, new AsyncCallback(CallWhenDone),del);
回撥方法:
static void CallWhenDone(IAsyncResult iar) { MyDel del = (MyDel)iar.AsyncState; long result = del.EndInvoke(iar); }
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對it145.com的支援。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45