日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

异步编程模式学习

發布時間:2023/12/9 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 异步编程模式学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????? 最近,在學習C#多線程編程,也看了園子里的很多大牛的關于多線程的文章,梳理下自己的思路,也總結下異步編程模式的學習。

?????很喜歡Jimmy Zhang的文章風格,在剛剛學習委托和事件的時候,Jimmy的文章的由淺入深的寫作對我對委托和事件的學習的幫助很大。我也學這個Jimmy的文風,和大家交流下。廢話不多說的,通過一個拋12點的小游戲的例子進入正題。

????沒有異步模式的多線程實現????????????????????????

?????? 游戲的規則:游戲隨機產生的0到12之間的數字,碰到數字12游戲結束。實現如下:例1

static void Main(string[] args){Thread thread = new Thread(new ThreadStart(ThreadFun));thread.Start();Console.WriteLine("Game is starting...");thread.Join();Console.WriteLine("Number 12 is createed.Game is over...");Console.ReadKey();}static void ThreadFun(){Random rnd = new Random();int rndNum;do{rndNum = rnd.Next(0, 13);Console.WriteLine(rndNum);} while (rndNum != 12);}

?

?????? 異步編程模式的實現

?這個小游戲的異步模式編程實現如下代碼:例2

delegate void asycInvoker();static void Main(string[] args){asycInvoker asycHander = ThreadFun;//此處是asycInvoker asycHander = new asycInvoker(ThreadFun)的快捷語法IAsyncResult result = asycHander.BeginInvoke(null,null);Console.WriteLine("Game is starting...");asycHander.EndInvoke(result);Console.WriteLine("Number 12 is createed.Game is over...");Console.ReadKey();}static void ThreadFun(){Random rnd = new Random();int rndNum;do{rndNum = rnd.Next(0, 13);Console.WriteLine(rndNum);} while (rndNum != 12);}

??? 異步編程模式和多線程的關系

???? 異步編程模式技術為多線程處理技術的強大擴展方式。C#的異步模式的內部的實現是通過線程池的掛起和釋放實現一步操作。C#的異步模式的好處降低創建和銷毀線程相關的成本,CLR為每一個進程維護一個線程池。

???? 由此,我們必須清楚線程池的優缺點的。線程池的優點是很明顯的,缺點是一旦加入線程池,就沒辦法控制程序的執行,程序的執行都在線程池的自動管理。

?? .NET的異步編程模式

????? Net 在設計的時候為異步編程設計了一個異步編程模型(APM),這個模型不僅是使用.NET的開發人員使用,.Net內部也頻繁用到。通過使用委托,我們可以異步實現委托列表上的方法(委托列表只能有一個方法)。委托類有兩個方法:叫做BeginInvoke和EndInvoke,他們就是用來實現異步操作過程。

????? 當我們調用委托的BeginInvoke方法時,它開始在線程池中的獨立線程上執行引用方法,并且立即返回原始線程。原始線程可以繼續,而引用方法會在線程池的線程中執行。

???? 當程序異步方法執行的時候,主線程和異步方法的線程池線程之間的同步過程不同處理,就會有不同的實現模式,當異步方法執行結束,可以檢查BeginInvoke返回的IAsyncResult的IsCompleted屬性,或者調用委托的EndInvoke方法等待委托的完成,或著在委托的回調方法中調用EndInvoke方法完成委托。

???? 上述過程有異步編程的3種標準模式的過程。這三種過程,原始線程都發起了一個異步方法,這些模式不同的是,原始線程獲得發起的線程已經完成的消息的方式。標準的三種模式有等待完成模式、輪詢模式和回調模式。通過代碼將每一種模式表述下:

????? 等待-結束模式

???? 在這個模式中,原始線程發起異步模式方法的調用,原始線程和異步方法所在的線程池線程并發(可能這里用并發描述不是很恰當)運行,如果原始線程一直到調用委托方法的EndInvoke時,委托方法還沒有執行完,原始線程就等待異步線程結束,如果有返回值的話,返回異步方法的返回值。代碼如例1所示。

???? AsyncResult類

?????? 在BeginInvoke方法的調用的時候,返回一個IAsyncResult接口的引用,在內部實現AsyncResult類的對象。AsyncResult類表現了異步方法的狀態。有關這個類的需要說明的如下:

  • ?我們調用委托對象的BeginInvoke方法時,系統創建了一個AsyncResult類的對象。BeingInvoke方法返回對象實現的接口的引用。
  • AsyncResult對象包含一個叫做AsyncDelegate的屬性,該屬性返回指向被調用的產生異步方法的委托對象的引用。
  • IsCompleted屬性表示異步方法是否完成。
  • AsyncState屬性作為BeginInvoke方法調用時的state參數,他返回object類型的引用。

?

????輪詢模式

?????? 在輪詢模式中,原始線程發起的異步方法的調用,原始線程就繼續執行,然后用IasyncResult的IsComplete屬性來定期檢查異步線程是否完成。如果異步方法已經完成,原始線程就調用EndInvoke并繼續,否則,繼續檢查執行。代碼實例3

delegate void asycInvoker();static void Main(string[] args){asycInvoker asycHander = new asycInvoker(ThreadFun);IAsyncResult result = asycHander.BeginInvoke(null,null);Console.WriteLine("Game is starting...");while (!result.IsCompleted){Console.WriteLine("Game is not completed...");//此處可以繼續執行其他的邏輯 }asycHander.EndInvoke(result);Console.WriteLine("Number 12 is createed.Game is over...");Console.ReadKey();}static void ThreadFun(){Thread.Sleep(100);//暫時掛起該線程,放大整個執行的過程Random rnd = new Random();int rndNum;do{rndNum = rnd.Next(0, 13);Console.WriteLine(rndNum);} while (rndNum != 12);}

?????回調模式

?????在前面的模式中,等待-結束和輪詢模式中,初始線程都是繼續自己的執行過程,等待異步的線程完成。然后,在EndInvoke獲得異步方法的返回值,并初始線程繼續后面的邏輯執行。在效率地上,輪詢通常不是最好的方法。所以,在異步編程中使用通知機制,能在一個異步方法完成時觸發一個方法。

????? 我們回到BeginInvoke方法的參數來談的,BeginInvoke的參數根據定義的委托類型不斷變化的,但是最后兩個參數是不會改變的,AsyncCllback委托類型的原型為:delegate void AsyncCallback(IAsyncResult result),最后一個參數為object類型,稍后會談到object類型解決的問題。回調的方法的通知機制關鍵就在AsyncCllback委托類型參數的使用,在AsyncCallback委托的實例中調用EndInvoke方法,返回異步方法的返回值,而AsyncCallback實例在異步方法一結束就調用。通過代碼演練實例4:

delegate void asycInvoker();static void Main(string[] args){asycInvoker asycHander = new asycInvoker(ThreadFun);IAsyncResult result = asycHander.BeginInvoke(new AsyncCallback(CallbackFun),null);Console.WriteLine("Game is starting...");Console.ReadKey();}static void CallbackFun(IAsyncResult result){AsyncResult asyncResult = (AsyncResult)result;asycInvoker handler = (asycInvoker)asyncResult.AsyncDelegate;handler.EndInvoke(result);Console.WriteLine("Number 12 is createed.Game is over...");}static void ThreadFun(){Console.WriteLine("asyncMethod is runing...");Random rnd = new Random();int rndNum;do{rndNum = rnd.Next(0, 13);Console.WriteLine(rndNum);} while (rndNum != 12);}

回調過程傳遞參數

?????? 為能具體的展示object類型參數的應用,這次將這個小程序的要求改變一下,我們可以隨機選擇結束的數字,游戲在產生我們需要的數字時結束。通過代碼的演示例5

delegate void asycInvoker(int endNum);static void Main(string[] args){Console.WriteLine("Select the End Number:");int endNum = int.Parse(Console.ReadLine());asycInvoker asycHander = new asycInvoker(ThreadFun);IAsyncResult result = asycHander.BeginInvoke(endNum,new AsyncCallback(CallbackFun),endNum);Console.WriteLine("Game is starting...");Console.ReadKey();}static void CallbackFun(IAsyncResult result){int endNum = (int)result.AsyncState;AsyncResult asyncResult = (AsyncResult)result;asycInvoker handler = (asycInvoker)asyncResult.AsyncDelegate;handler.EndInvoke(result);Console.WriteLine("Number {0} is createed.Game is over...",endNum);//此處為傳遞的參數的用途 }static void ThreadFun(int endNum){Console.WriteLine("asyncMethod is runing...");Random rnd = new Random();int rndNum;do{rndNum = rnd.Next(0, endNum);Console.WriteLine(rndNum);} while (rndNum != 12);}

???? 關于異步編程的使用,推薦老趙的博客寫到的正確使用異步操作。

????????以上是我對學習異步編程模式的知識的梳理,在大神云集的園子里,作為.NET入門新手,不求聞達,希望能為園子里樂于分享的精神能有所發揚,也希望能對園子里的新手們有所幫助,能得到牛人的指導。

?

?

???????

?

?

?

?

?

????

????

?

轉載于:https://www.cnblogs.com/Johnnie/archive/2012/08/20/Async.html

總結

以上是生活随笔為你收集整理的异步编程模式学习的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。