異步是現實生活中的不少現象的一種抽象。好比分工合做在不少時間段就是異步合做。異步中也通常要涉及委託方法。c#有3種模式的異步編程:異步模式,基於事件的異步模式,基於任務的異步模式(TAP).html
一. FrameWork 4.0以前的線程世界 編程
在.NET FrameWork 4.0以前,若是咱們使用線程。通常有如下幾種方式:c#
二. .Net 傳統異步編程概述 異步
三. Task 的優勢以及功能 async
第一種 異步模式 異步編程
public class 異步調用 { static void Main() { Console.WriteLine("===== 異步調用 AsyncInvokeTest ====="); AddHandler handler = new AddHandler(加法類.Add); //IAsyncResult: 異步操做接口(interface) //BeginInvoke: 委託(delegate)的一個異步方法的開始 IAsyncResult result = handler.BeginInvoke(1, 2, null, null); Console.WriteLine("繼續作別的事情。。。"); //異步操做返回 EndInvoke方式會阻塞主線程 須要等待異步線程調用完畢 纔會執行 Console.WriteLine(handler.EndInvoke(result)); Console.ReadKey(); } }
public class 異步回調 { static void Main() { Console.WriteLine("===== 異步回調 AsyncInvokeTest ====="); AddHandler handler = new AddHandler(加法類.Add); //異步操做接口(注意BeginInvoke方法的不一樣!) IAsyncResult result = handler.BeginInvoke(1,2,new AsyncCallback(回調函數),"AsycState:OK"); Console.WriteLine("繼續作別的事情。。。"); Console.ReadKey(); } static void 回調函數(IAsyncResult result) { //result 是「加法類.Add()方法」的返回值 //AsyncResult 是IAsyncResult接口的一個實現類,空間:System.Runtime.Remoting.Messaging //AsyncDelegate 屬性能夠強制轉換爲用戶定義的委託的實際類。 AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate; //或者 AddHandler handler=result.AsyncState as AddHandler; Console.WriteLine(handler.EndInvoke(result)); Console.WriteLine(result.AsyncState); } }
利用lambda表達式簡單寫法 (這個很經常使用。必定要理解和學會。)函數
// public delegate string TakesAWhileDelegate(int data1, int data2); 定義一個委託 TakesAWhileDelegate dl = (a, b) => { return (a + b).ToString(); }; //委託 實例化 dl.BeginInvoke(1, 12, result => { //回調方法 實例化 string str=dl.EndInvoke(result); //EndInvoke方法取回結果 Console.WriteLine("取到異步的結果了result={0}", str); }, null);
第二種 基於事件的異步模式網站
.net中不少類的方法都定義了同步和異步兩種模式,例如WebClient類,就定義了DownloadStringAsync基於事件的異步模式。.net
WebClient wc = new WebClient(); string strUI = "我是主線程中的元素"; wc.Encoding = Encoding.UTF8; //首先實例化 Completed事件。 注意:能夠直接訪問UI線程中的元素 // public delegate void DownloadStringCompletedEventHandler(object sender, DownloadStringCompletedEventArgs e); wc.DownloadStringCompleted += (sender1, e1) => { //e1 存放結果 Console.WriteLine(strUI); string str = e1.Result; Console.WriteLine(str); }; wc.DownloadStringAsync(new Uri("http://www.baidu.com")); Console.WriteLine("繼續主線程,不會由於訪問網站而阻塞");
第三種 基於任務的異步模式(Task,await,async關鍵字)線程
private void button21_Click(object sender, EventArgs e) { Console.WriteLine("主線程已經開始了"); CallerWithAsync(); //調用基於任務的異步方法 Console.WriteLine("主線程已經結束了"); } //建立基於任務的異步方法 private async void CallerWithAsync() { //async(方法修飾符)和await必須成對出現。順序執行 string result = await GetAsync("第1個"); //等待 方法執行結果 阻塞線程。編譯器把await關鍵字後的全部代碼放進ContinueWith方法的代碼塊中 string result2 = await GetAsync("第2個"); Console.WriteLine("任務第3"); } //經過任務使同步方法異步化 private Task<string> GetAsync(string name) { return Task.Run<string>(() => { Thread.Sleep(2000); Console.WriteLine(name); return name; }); }
TASK的用法 請參考這篇文章