Asp.Net異步編程編程
寫在前面的話,好久沒有寫Blog了,不對,其實一致就沒有怎麼寫過.今天有空,我也來寫一篇Blog網絡
隨着.Net4.5的推出,一種新的編程方式簡化了異步編程,在網上時不時的也看到各類打着Asp.Net異步編程的口號,如何提升性能,如何提升吞吐率!多線程
好多文章都說得不清楚,甚至是錯誤的.只看到了一些表象,混淆概念.但願這篇文章可以可以對一部分人理解Asp.net異步編程模型.asp.net
本文的重點是理解Asp.net異步如何提升吞吐率,提升性能.固然提升性能的不單是異步,有不少方式,多線程等等.異步
1基礎知識,談一個初學者不容易理解的基礎知識,這個基礎知識,很不基礎的哦async
先看這個代碼異步編程
ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);性能
Asp.net有二類線程,1類就是工做線程,另外一類是IO線程,也有叫完成端口線程.簡單說一下,工做線程:處理普通請求的線程,日常代碼中運用得最多的線程.spa
這個線程是有限的,是根CPU的個數相關的.IO線程,就是好比與文件讀寫,網絡操做等就能夠異步實現真正意義的性能提高[異步]..net
這個IO線程若是沒有專門處理,一般狀況下也是沒有處理的,這個IO線程基本上都是空閒的
就是可使用IO線程來代替工做線程,由於處理用戶請求的是工做線程,是有限的,比較珍貴的。
2ThreadPool,Task這二個其實都是線程,對於Asp.net來講,代碼沒有作特殊的處理一般都是工做線程,線程池裏的線程
Thread這個是底層的線程,沒有作任何封裝,直接使用,建立這個線程比較費時,同時不容易重用.
3async/await一個新的語法糖,一個簡化方式的異步編程模型,值得推薦.有了這個後,咱們的異步編程模型變得簡單,優雅--這個和Task關係很緊密的,如何...本身去實踐
以上幾個概念瞭解後,咱們就是使用最佳實踐,提升性能,吞吐率了
下面給出一個WebApi的示例
public async Task<string> Get() { return await GetArticleContentAsync(); } private async Task<string> GetArticleContentAsync() { using (var httpClient = new HttpClient()) { var response = await httpClient.GetAsync("http://www.asp.net"); var buffer = await response.Content.ReadAsByteArrayAsync(); return Encoding.UTF8.GetString(buffer); } }
這個代碼,看起來和網上其餘的Blog差很少,但這樣的方式對於asp.net異步,提高吞吐率的效果是最佳的,第1,使用IO端口,在處理網絡請求的時候[從http://www.asp.net獲取數據的時候]
把當時處理的工做線程返回給了線程池,讓其能夠處理其餘用戶的請求,在從網絡www.asp.net獲取數據的時候,只佔用了一個IO線程
如今列出,網上其餘Blog的關於這塊的
public async Task<string> GetArticleContentByNoRigntWayAsync() { return await Task.Run(() => { using (var client = new WebClient()) { return client.DownloadString("http://www.asp.net"); } }); }
這個代碼看起來和上面的代碼沒有什麼區別,可是這樣代碼和上面的第一種方式是有本質的區別,性能真的有提高嗎?真的能提高吞吐率嗎?好多開發也是這樣使用的
我先在這兒給出答案,這樣的方式[使用GetArticleContentByNoRigntWayAsync],是不太可能提高性能的,特別是在Asp.net環境中
這兒的確用於了異步,也用到了Task,線程池.僅僅用到了而已
想知道爲何沒有提高性能,沒有提升吞吐率,須要各位客觀的支持
接着昨天沒有說完的,繼續說!
把同步方法封閉成異步,在Asp.net中只會佔用線程池的線程池,同時也可能會形成線程間的切換,至於線程池的切換耗時不,我不清楚,可是已經在關注性能問題了,那咱們就
應該避免線程切換,切換總比不切換耗時,對吧
咱們要使用並行計算,咱們直接使用使用同步,再加上幾個Task就能夠了,若是隻有一個Task,又是同步,也沒有必要.
因此對於咱們使用言我總結一下
使用異步,就要使用IO線程,充分利用這個去完成操做
若是沒有使用IO線程,就直接使用同步會更好
1異步+IO線程
2直接同步
3並行計算[充分利用CPU] 同步+二個以上的Task
a並行期間吞吐率會降低,若是CPU有空閒的話,能夠考慮本身實現一個線程池[使用Thread],一般不易寫穩定
b[建議]把ThreadPool的默認數量改大些,前提仍是CPU有空閒的話
寫在最後的話,這Blog有8人推薦,5人反對->文章還寫得不夠好啊,對不起你們了
今天起來,被編輯推薦了,內心仍是很高興的,第一次被編輯推薦啊.感謝你們的評論支持,不論是支持,仍是反對的
要是DUDU跟我開事後門,把這文章成爲精選就更....開玩笑的,哈哈
若是以爲還有點點價值的,請點右下角 推薦