亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

實現基于Task的異步模式

2019-11-14 13:54:00
字體:
來源:轉載
供稿:網友

返回該系列目錄《基于Task的異步模式--全面介紹》

生成方法

編譯器生成

在.NET Framework 4.5中,C#編譯器實現了TAP。任何標有async關鍵字的方法都是異步方法,編譯器會使用TAP執行必要的轉換從而異步地實現方法。這樣的方法應該返回Task或者Task<TResult>類型。在后者的案例中,方法體應該返回一個TResult,且編譯器將確保通過返回的Task<TResult>是可利用的。相似地,方法體內未經處理的異常會被封送到輸出的task,造成返回的Task以Faulted的狀態結束。一個例外是如果OperationCanceledException(或派生類型)未經處理,那么返回的Task會以Canceled狀態結束。

手動生成

開發者可以手動地實現TAP,就像編譯器那樣或者更好地控制方法的實現。編譯器依賴來自System.Threading.Tasks命名空間暴露的公開表面區域(和建立在System.Threading.Tasks之上的System.Runtime.CompilerServices中支持的類型),還有對開發者直接可用的功能。當手動實現TAP方法時,開發者必須保證當異步操作完成時,完成返回的Task。

混合生成

在編譯器生成的實現中混合核心邏輯的實現,對于手動實現TAP通常是很有用的。比如這種情況,為了避免方法直接調用者產生而不是通過Task暴露的異常,如:

public Task<int> MethodAsync(string input){    if (input == null) throw new ArgumentNullException("input");    return MethodAsyncInternal(input);}PRivate async Task<int> MethodAsyncInternal(string input){    … // code that uses await}

參數應該在編譯器生成的異步方法之外改變,這種委托有用的另一種場合是,當一個“快速通道”優化可以通過返回一個緩存的task來實現的時候。

工作負荷

計算受限和I/O受限的異步操作可以通過TAP方法實現。然而,當TAP的實現從一個庫公開暴露時,應該只提供給包含I/O操作的工作負荷(它們也可以包含計算,但不應該只包含計算)。如果一個方法純粹受計算限制,它應該只通過一個異步實現暴露,消費者然后就可以為了把該任務卸載給其他的線程的目的來選擇是否把那個同步方法的調用包裝成一個Task,并且/或者來實現并行。

計算限制

Task類最適合表示計算密集型操作。默認地,為了提供有效的執行操作,它利用了.Net線程池中特殊的支持,同時也對異步計算何時,何地,如何執行提供了大量的控制。

生成計算受限的tasks有幾種方法。

  1. 在.Net 4中,啟動一個新的計算受限的task的主要方法是TaskFactory.StartNew(),該方法接受一個異步執行的委托(一般來說是一個Action或者一個Func<TResult>)。如果提供了一個Action,返回的Task就代表那個委托的異步執行操作。如果提供了一個Func<TResult>,就會返回一個Task<TResult>。存在StartNew()的重載,該重載接受CancellationToken,TaskCreationOptions,和TaskScheduler,這些都對task的調度和執行提供了細粒度的控制。作用在當前調度者的工廠實例可以作為Task類的靜態屬性,例如Task.Factory.StartNew()。
  2. 在.Net 4.5中,Task類型暴露了一個靜態的Run方法作為一個StartNew方法的捷徑,可以很輕松地使用它來啟動一個作用在線程池上的計算受限的task。從.Net 4.5開始,對于啟動一個計算受限的task,這是一個更受人喜歡的機制。當行為要求更多的細粒度控制時,才直接使用StartNew。
  3. Task類型公開了構造函數和Start方法。如果必須要有分離自調度的構造函數,這些就是可以使用的(正如先前提到的,公開的APIs必須只返回已經啟動的tasks)。
  4. Task類型公開了多個ContinueWith的重載。當另外一個task完成的時候,該方法會創建新的將被調度的task。該重載接受CancellationToken,TaskCreationOptions,和TaskScheduler,這些都對task的調度和執行提供了細粒度的控制。
  5. TaskFactory類提供了ContinueWhenAll 和ContinueWhenAny方法。當提供的一系列的tasks中的所有或任何一個完成時,這些方法會創建一個即將被調度的新的task。有了ContinueWith,就有了對于調度的控制和任務的執行的支持。

思考下面的渲染圖片的異步方法。task體可以獲得cancellation token為的是,當渲染發生的時候,如果一個撤銷請求到達后,代碼可能過早退出。而且,如果一個撤銷請求在渲染開始之前發生,我們也可以阻止任何的渲染。

public Task<Bitmap> RenderAsync(    ImageData data, CancellationToken cancellationToken){    return Task.Run(() =>    {        var bmp = new Bitmap(data.Width, data.Height);        for(int y=0; y<data.Height; y++)        {            cancellationToken.ThrowIfCancellationRequested();            for(int x=0; x<data.Width; x++)            {                … // render pixel [x,y] into bmp            }        }        return bmp;    }, cancellationToken);}

如果下面的條件至少一個是正確的,計算受限的tasks會以一個Canceled狀態的結束:

  1. 在Task過度到TaskStatus.Running狀態之前,CancellationToken為一個發出撤銷請求的創建方法的參數提供(如StartNew,Run)。
  2. 有這樣的一個Task,它內部有未處理的OperationCanceledException。該OperationCanceledException 包含和CancellationToken屬性同名的CancellationToken傳遞到該Task,且該CancellationToken已經發出了撤銷請求。

如果該Task體中有另外一個未經處理的異常,那么該Task就會以Faulted的狀態結束,同時在該task上等待的任何嘗試或者訪問它的結果都將導致拋出異常。

I/O限制

使用TaskCompletionSource<TResult>類型創建的Tasks不應該直接被全部執行的線程返回。TaskCompletionSource<TResult>暴露了一個返回相關的Task<TResult>實例的Task屬性。該task的生命周期通過TaskCompletionSource<TResult>實例暴露的方法控制,換句話說,這些實例包括SetResult, SetException, SetCanceled, 和它們的TrySet* 變量。

思考這樣的需求,創建一個在特定的時間之后會完成的task。比如,當開發者在UI場景中想要延遲一個活動一段時間時,這可能使有用的。.NET中的System.Threading.Timer類已經提供了這種能力,在一段特定時間后異步地調用一個委托,并且我們可以使用TaskCompletionSource<TResult>把一個Task放在timer上,例如:

public static Task<DateTimeOffset> Delay(int millisecondsTimeout){    var tcs = new TaskCompletionSource<DateTimeOffset>();    new Timer(self =>    {        ((IDisposable)self).Dispose();        tcs.TrySetResult(DateTimeOffset.UtcNow);    }).Change(millisecondsTimeout, -1);    return tcs.Task;}

在.Net 4.5中,Task.Delay()就是為了這個目的而生的。比如,這樣的一個方法可以使用到另一個異步方法的內部,以實現一個異步的輪訓循環:

public static async Task Poll(    Uri url,     CancellationToken cancellationToken,     iprogress<bool> progress){    while(true)    {        await Task.Delay(TimeSpan.FromSeconds(10), cancellationToken);        bool success = false;        try        {            await DownloadStringAsync(url);            success = true;        }        catch { /* ignore errors */ }        progress.Report(success);    }}

沒有TaskCompletionSource<TResult>的非泛型副本。然而,Task<TResult>派生自Task,因而,泛型的TaskCompletionSource<TResult>可以用于那些 I/O受限的方法,它們都利用一個假的TResult源(Boolean是默認選擇,如果開發者關心Task向下轉型的Task<TResult>的消費者,那么可以使用一個私有的TResult類型)僅僅返回一個Task。比如,開發的之前的Delay方法是為了順著產生的Task<DateTimeOffset>返回當前的時間。如果這樣的 一個結果值是不必要的,那么該方法可以通過下面的代碼取而代之(注意返回類型的改變和TrySetresult參數的改變):

public static Task Delay(int millisecondsTimeout){    var tcs = new TaskCompletionSource<bool>();    new Timer(self =>    {        ((IDisposable)self).Dispose();        tcs.TrySetResult(true);    }).Change(millisecondsTimeout, -1);    return tcs.Task;}

混合計算限制和I/O限制的任務

異步方法不是僅僅受限于計算受限或者I/O受限的操作,而是可以代表這兩者的混合。實際上,通常情況是不同性質的多個異步操作被組合在一起生成更大的混合操作。比如,思考之前的RenderAsync方法,該方法基于一些輸入的ImageData執行一個計算密集的操作來渲染一張圖片。該ImageData可能來自于一個我們異步訪問的Web服務:

public async Task<Bitmap> DownloadDataAndRenderImageAsync(    CancellationToken cancellationToken){    var imageData = await DownloadImageDataAsync(cancellationToken);    return await RenderAsync(imageData, cancellationToken);}

這個例子也展示了一個單獨的CancellationToken是如何通過多個異步操作被線程化的。

返回該系列目錄《基于Task的異步模式--全面介紹》



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久国产精品久久国产精品| 国产亚洲精品久久| 亚洲精品美女久久久久| 亚洲成人三级在线| 96pao国产成视频永久免费| 国产亚洲欧美另类中文| 久久在线免费视频| 久久精品国产清自在天天线| 亚洲色图国产精品| 最好看的2019年中文视频| 久久99久久亚洲国产| 亚洲精品自在久久| 久久夜色精品国产| 成人观看高清在线观看免费| 欧美成人第一页| 欧美国产在线电影| 午夜精品久久久久久99热软件| 日本成人黄色片| 欧美日韩不卡合集视频| 成人亚洲综合色就1024| 97精品一区二区视频在线观看| 欧美一区二区三区四区在线| 亚洲综合中文字幕在线观看| 欧美尤物巨大精品爽| 欧美专区第一页| 日韩在线观看电影| 成人写真视频福利网| 欧美一级在线播放| 久久九九精品99国产精品| 国产国语videosex另类| 亚洲免费一级电影| 亚洲成人激情在线观看| 亚洲国产三级网| 久久久久久国产精品三级玉女聊斋| 国产精品电影一区| 久久久久久久999| 亚洲激情成人网| 91视频免费在线| 成人福利免费观看| 九九精品在线视频| 亚洲毛茸茸少妇高潮呻吟| 亲爱的老师9免费观看全集电视剧| 2019亚洲男人天堂| 在线观看精品国产视频| x99av成人免费| 国产亚洲a∨片在线观看| 羞羞色国产精品| 国产经典一区二区| 精品国产区一区二区三区在线观看| 91亚洲精华国产精华| 一区二区av在线| 国产中文日韩欧美| 国产精品亚洲欧美导航| 中文字幕日韩欧美在线| 亚洲一区亚洲二区| 成人激情免费在线| 欧美肥老妇视频| 国产精品午夜一区二区欲梦| 欧美一区视频在线| 日韩在线观看免费网站| 国内揄拍国内精品少妇国语| 久久久精品日本| 国自在线精品视频| 亚洲激情中文字幕| 国产男女猛烈无遮挡91| 久久亚洲春色中文字幕| 一区二区三区精品99久久| 亚洲精品福利视频| 欧美一级高清免费播放| 中文字幕av一区| 久久999免费视频| 国产精品视频区| 日韩精品中文字幕在线| 亚洲精品国精品久久99热| 91久久在线播放| 亚洲日韩中文字幕在线播放| 国产中文日韩欧美| 欧美成人黄色小视频| 少妇av一区二区三区| 欧美日韩一区二区三区| 97精品国产91久久久久久| 国产伦精品一区二区三区精品视频| 亚洲国产精品久久91精品| 国产成人精品a视频一区www| 亚洲乱码一区av黑人高潮| 久热精品视频在线免费观看| 性色av一区二区三区红粉影视| 久久久999国产| 国产亚洲一区精品| 久久久久久成人| 久久香蕉频线观| 69视频在线免费观看| 亚洲第一二三四五区| 欧美另类老女人| 欧美国产日韩一区二区三区| 国产99久久精品一区二区永久免费| 91色在线观看| 久久久综合免费视频| 国产精品video| 国产精品久久久久影院日本| 亚洲成av人乱码色午夜| 成人性生交xxxxx网站| 中文字幕久久精品| 久久久久久这里只有精品| 国产精品尤物福利片在线观看| 国产精品青青在线观看爽香蕉| 国产一区二区三区三区在线观看| 亚洲亚裔videos黑人hd| 久久免费国产精品1| 日韩av免费看| 日韩精品免费综合视频在线播放| 欧美日韩国产在线看| 永久555www成人免费| 精品久久久在线观看| 亚洲高清久久久久久| 日韩亚洲精品视频| 久久精品美女视频网站| 日韩三级影视基地| 欧美午夜影院在线视频| 色天天综合狠狠色| 日韩少妇与小伙激情| 亚洲女人天堂视频| 亚洲自拍偷拍区| 姬川优奈aav一区二区| 成人激情免费在线| 亚洲伊人成综合成人网| 成人激情视频免费在线| 成人观看高清在线观看免费| 亚洲视频在线看| 欧美另类极品videosbest最新版本| 日本中文字幕不卡免费| 国产亚洲综合久久| 成人午夜激情免费视频| 日韩av大片免费看| 欧美亚洲国产视频小说| 精品久久中文字幕久久av| 欧美视频一二三| 美女性感视频久久久| 日韩经典中文字幕在线观看| 另类美女黄大片| 亚洲欧美日韩天堂一区二区| 欧美日韩综合视频| 国产精品久久av| 日韩成人av在线播放| 久久精品美女视频网站| 国产精品视频26uuu| 亚洲午夜小视频| 欧美三级欧美成人高清www| 国产亚洲欧美视频| 久久天天躁狠狠躁夜夜躁| 亚洲人成网7777777国产| 欧美国产视频一区二区| 欧美精品情趣视频| 岛国精品视频在线播放| 日韩69视频在线观看| 欧美色另类天堂2015| 欧美日韩中文字幕日韩欧美| 国产精品自拍视频| 51精品在线观看| 午夜精品久久久久久久久久久久久| 欧美特黄级在线| 91精品国产91久久久久久吃药| 中文字幕亚洲欧美日韩在线不卡| 亚洲毛片在线看|