開篇 每一個版本的.net都會引入一些新的特性,這些特性方便開發人員能夠快速實現一些功能。雖然.net版本一直在更新,但是新版本對舊版本的程式都是相容的,在這一點上微軟做的還是非常好的。每次學一個新內容,第一次接觸的方法在腦海裡占的位置還是比較重要的,從剛開始接觸.net的多線程編程是使用Threa ...
開篇
每一個版本的.net都會引入一些新的特性,這些特性方便開發人員能夠快速實現一些功能。雖然.net版本一直在更新,但是新版本對舊版本的程式都是相容的,在這一點上微軟做的還是非常好的。每次學一個新內容,第一次接觸的方法在腦海裡占的位置還是比較重要的,從剛開始接觸.net的多線程編程是使用Thread類,然後後面寫的程式只要用到非同步或者多線程就馬上會想到用Thread,雖然知道委托的非同步調用也能夠實現,但是腦海裡面的排在前面還是Thread類,在那個時候不知道他們之間的區別和優劣,也就不懂得如何去取捨。到了.net4.0引入了Task這個任務類,讓我們用少量的代碼就開始實現了多線程編程,從這個時候開始我也慢慢的瞭解了.net裡面的有哪一些非同步實現的方式以及多線程內部的一些機制,也知道它們各自的優勢。在接觸Task類的時候.net4.5也發佈出來了,並且帶來一個更加方便的關鍵字(async,await),輕鬆實現函數非同步調用。雖然知道async和await修飾符,但是自己卻遲遲沒有接觸,因為平常的工作中使用Task類就基本能實現我想要的效果。最近看了一些源碼,源碼中有很多代碼是應用了async和await的關鍵字來實現非同步的,所以我也不得不去學習,接觸之後發現,使用async和await關鍵字確實簡化了以前非同步編程所需要的步驟,也比較好理解。下麵通過一些小例子來簡述async和await修飾符如何實現非同步編程以及和以前使用Task類來實現非同步編程的少許區別。另外,關於.net4.0(包含)以前的的非同步編程模式可以參考我的另外一篇博文:http://www.cnblogs.com/mingjiatang/p/5267391.html
1 async和await實現方法非同步調用
下麵看一段由async定義的非同步方法以及非同步方法的調用代碼,如下:static void Main(string[] args) { AsyncMethod(10);//no.1 Console.WriteLine("執行其他的東西,當前線程id:{0}", Thread.CurrentThread.ManagedThreadId);//out.4 Console.ReadKey(); } static async void AsyncMethod(int i) { Console.WriteLine("非同步方法開始,當前線程id:{0}",Thread.CurrentThread.ManagedThreadId);//out.1 await AsyncTaskMethod(i);//no.3 Console.WriteLine("非同步方法退出,當前線程id:{0}", Thread.CurrentThread.ManagedThreadId);////out.6 } public static async Task<int> AsyncTaskMethod(int i) { Console.WriteLine("【任務】開始,當前線程id:{0}", Thread.CurrentThread.ManagedThreadId);//out.2 Task<int> t = Task.Run(() => { Console.WriteLine("【任務】正在執行,執行任務的線程id:{0}", i, Thread.CurrentThread.ManagedThreadId);//out.3 Thread.Sleep(2000); return i; });//no.4 int r= await t;//no.5 Console.WriteLine("【任務】執行完成,當前線程id:{0}", i, Thread.CurrentThread.ManagedThreadId);//out.5 return r; }
下麵是執行結果:

小結
其實在async和await關鍵字的非同步實現依然是使用線程池中的線程。個人認為,內部是使用Task類實現的,只是在任務結束時的回調比單獨使用Task要簡單一些。單獨使用Task類實現非同步時,當任務完成要進行回調,需要對Task對象調用ContinueWith方法,綁定任務結束後的回調函數並傳遞相關參數。而使用async和await實現非同步時,只需要使用Task去執行任務,然後用await去等待任務執行的結果就好了,並不會阻塞主線程的運行,整個編碼過程和同步實現差不多,這個例子就是一個很好的說明。 --------------------------------最後再說明一下async和await使用要點和作用------------------------------------------1、非同步的方法(包括匿名方法,和lambda表達式)必須要使用async修飾 2、非同步方法可以具有返回類型的 void, Task,或 Task< TResult> 。該方法不能聲明任何 ref 或 出參數,儘管它可以調用具有此類參數的方法。其中返回值為TRsult時,返回類型就是 Task< TResult>。 3、await 運算符應用於一個非同步方法的任務掛起方法的執行,直到等待任務完成。 任務表示正在進行的工作。 4、await 表達式不阻止調用它的線程。 當任務完成時,將會調用其延續任務,並且,非同步方法的執行恢復它將會停止的位置。換句話說就是:await會讓當前方法等待Task執行完畢再執行。