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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

常见的异步方式async 和 await

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

之前研究過c#的async和await關鍵字,幕后干了什么,但是不知道為什么找不到相關資料了。現在重新研究一遍,順便記錄下來,方便以后查閱。

基礎知識

async 關鍵字標注一個方法,該方法返回值是一個Task、或者Task<TResult>、void、包含GetAwaiter方法的類型。該方法通常包含一個await表達式。該表達式標注一個點,將被某個異步方法回跳到該點。并且,當前函數執行到該點,將立刻返回控制權給調用方。

以上描述了async方法想干的事情,至于如何實現,這里就不涉獵了。

個人見解

由此可以知道,async 和await關鍵字主要目的是為了控制異步線程的同步,讓一個異步過程,表現得好像同步過程一樣。

比如async 方法分n個任務去下載網頁并進行處理:先await下載,然后立刻返回調用方,之后的處理就由異步線程完成下載后調用。這時候調用方可以繼續執行它的任務,不過,如果調用方立刻就需要async的結果,那么應該就只能等待,不過大多數情況:他暫時不需要這個結果,那么就可以并行處理這些代碼。

可見,并行性體現在await 上,如果await 點和最終的數據結果距離越遠,那么并行度就越高。如果await的點越多,相信也會改善并行性。

資料顯示,async 和await 關鍵字并不會創建線程,這是很關鍵的一點。他們只是創建了一個返回點,提供給需要他的線程使用。那么線程究竟是誰創建?注意await 表達式的組成,他需要一個Task,一個Task并不代表一定要創建線程,也可以是另一個async方法,但是層層包裹最里面的方法,很可能就是一個原生的Task,比如await Task.Run(()=>Thread.Sleep(0)); ,這個真正產生線程的語句,就會根據前面那些await點,逐個回調。

從這點來看,async 方法,未必就是一個異步方法,他在語義上更加貼近“非阻塞”, 當遇到阻塞操作,立刻用await定點返回,至于其他更深一層的解決手段,它就不關心了。這是程序員需要關心的,程序員需要用真正的創建線程代碼,來完成異步操作(當然這一步可由庫程序員完成)。

注意async的幾個返回值類型,這代表了不同的使用場景。如果是void,說明客戶端不關心數據同步問題,它只需要線程的控制權立刻返回。可以用在ui 等場合,如果是Task,客戶端也不關心數據,但是它希望能夠控制異步線程,這可能是對任務執行順序有一定的要求。當然,最常見的是Task<TResult>。

綜上,async和await并不是為了多任務而設計的,如果追求高并發,應該在async函數內部用Task好好設計一番。在使用async 和await的時候,只需要按照非阻塞的思路去編寫代碼就可以了,至于幕后怎么處理就交給真正的多線程代碼創建者吧。

示范代碼

static async Task RunTaskAsync(int step){for(int i=0; i < step; i++){await Task.Run(()=>Thread.Sleep(tmloop));//點是靜態的,依次執行Thread.Sleep(tm2);}Thread.Sleep(tm3);}//客戶端Task tk= RunTaskAsync(step);Thread.Sleep(tm1);//這一段是并行的,取max(函數,代碼段)最大時間tk.Wait( );//這里代表最終數據

為了達到高度并行,應該用真正的多線程代碼:

static async Task RunTaskByParallelAsync(int step){await Task.Run(()=>Parallel.For(0,step,s=>{loop(tmloop);loop(tm2);}));loop(tm3);}

并行編碼方法

并行執行有幾個方法,第一個是創建n個Task,一起啟動。問題是怎么處理await點。每個task寫一個await點是不行的,因為遇到第一個await就立刻返回,而不會開啟所有任務并行執行。因此await不能隨便放。那么如何為一組Task設定await點呢?可以通過Task.WhenAll 這個方法,他會等待一組Task執行完畢返回。

特定情況下,可以用Parallel.For 來開啟一組任務,但是這個類并沒有實現async模式,也就是它會阻塞當前線程,所以需要用一個Task來包裹它。

可見,非阻塞和并行不完全是一回事。

總結

以上是生活随笔為你收集整理的常见的异步方式async 和 await的全部內容,希望文章能夠幫你解決所遇到的問題。

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