1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        .NET并發(fā)編程-異步編程模型上

        共 4366字,需瀏覽 9分鐘

         ·

        2021-03-25 23:20

        寫給普通:

        時間撲面而來,我們終將釋懷

        健康的活著,平靜的過著

        開心的笑著,適當?shù)拿χ?/span>

        本系列學習在.NET中的并發(fā)并行編程模式,實戰(zhàn)技巧

        本小節(jié)開始學習任務編程模型。本系列保證最少代碼呈現(xiàn)量,雖然talk is cheap, show me the code被奉為圭臬,我的學習習慣是,只學習知識點,代碼不在當下立馬要用的時候不會認真去讀的,更何況在大多時候在手機閱讀更不順暢。


        本小節(jié)介紹任務異步模型。作為開發(fā)人員,異步編程是對你技能集的一個重要補充。


        1、異步編程模型APM


        異步(asynchronous)操作是指請求開始不需要等待請求的返回,請求完成后再切換回來,期間可以做其他事情。就是不會閑著等待任何一個操作的完成

        并行主要和應用程序性能有關,它還可以利用現(xiàn)代多核計算機結構,增強對多線程CPU密集型工作,異步是并發(fā)的超集,主要面向I/O密集型操作,而不是CPU密集型操作。異步解決了延遲問題(任何需要很長時間才能運行的問題)。


        2、.NET中的異步支持


        2.1 Begin/End模式


        原始的異步編程模式是將一個長時間運行的函數(shù)分為兩個部分,一部分負責啟動異步操作Begin,另一部分負責完成時回調End,稱之為Begin/End模型以讀取文件為例的同步和異步編程如下所示


        void ReadFileBlocking(string filePath, Action<byte[]> process){    using (var fileStream = new FileStream(filePath, FileMode.Open,                                  FileAccess.Read, FileShare.Read))    {        byte[] buffer = new byte[fileStream.Length];        int bytesRead = fileStream.Read(buffer, 0, buffer.Length);        process(buffer);    }}
        //以下為異步讀取IAsyncResult ReadFileNoBlocking(string filePath, Action<byte[]> process){ using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 0x1000, FileOptions.Asynchronous)) { byte[] buffer = new byte[fileStream.Length]; var state = Tuple.Create(buffer, fileStream, process); return fileStream.BeginRead(buffer, 0, buffer.Length, EndReadCallback, state); }}
        void EndReadCallback(IAsyncResult ar){ var state = ar.AsyncState as Tuple<byte[], FileStream, Action<byte[]>>; using (state.Item2) state.Item2.EndRead(ar); state.Item3(state.Item1);}


        上面EndReadCallback就是讀取完成后的回調函數(shù),什么是回調,回調是一個用于加快程序速度的函數(shù)。異步編程使用回調創(chuàng)建新的線程來獨立地運行方法。在異步運行時,程序通過一個用于注冊另一個函數(shù)的延續(xù)的可重入函數(shù)來通知調用函數(shù)任何更新,包括失敗、取消、進度和完成。這個過程需要一些時間才能產生結果。


        Begin/End模式,將開始和回調通知分離開,代碼看起來不像順序結構那么順眼。并且像上例state變量一樣,我們需要維護一個狀態(tài)以保證回調函數(shù)能訪問到。


        2.2 基于事件的異步編程


        EAP(Event-based Asynchronous Programming)基于事件的異步編程模式是從.NET2開始引入。用事件代替以往的回調,但仍然不能剝離方法調用和事件處理程序。


        3、基于任務異步編程模型


        TAP模型淘汰了APM和EAP,如果你是C#使用者,建議使用TAP模型。TAP為異步代碼提供了一種干凈的聲明式風格。


        C#5.0開始,對象Task和Task<T>在關鍵字async和await的支持下,已經成為異步操作模型的主要組件。TAP模型只通過純粹關注語法方面就解決了回調問題,從而繞過了推理代碼中表達的事件序列出現(xiàn)的困難。C#5.0中的異步函數(shù)解決了耗費運行時間的延遲問題。


        TAP核心思想就是將異步操作包進一個Task里面。異步執(zhí)行的話,使用async關鍵字通知編譯器該方法異步運行不阻塞。上面讀取文件例子改為TAP模型如下

        async Task ReadFileNoBlockingAsync(string filePath, Func<byte[], Task> process){    using (var fileStream = new FileStream(filePath, FileMode.Open,                                    FileAccess.Read, FileShare.Read, 0x1000,                                    FileOptions.Asynchronous))    {        byte[] buffer = new byte[fileStream.Length];        int bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length);        await process(buffer);    }}


        當運行到await關鍵字時,它會掛起調用方法并將控制權交換給它的調用者,直到所等待的任務完成為止。


        3.1 異步取消


        以下是用于取消Task或異步操作相關的.NET類型:


        • CancellationTokenSource負責創(chuàng)建取消令牌,并向該令牌的所有拷貝發(fā)送取消請求

        • CancellationToken是用于監(jiān)控當前令牌狀態(tài)的結構。


        TAP模型中的取消支持,創(chuàng)建任務時傳遞取消令牌,然后異步操作會檢查令牌的狀態(tài),并在觸發(fā)請求時取消計算像下面所示:

        CancellationTokenSource cts = new CancellationTokenSource();  // 取消令牌
        async Task<string> DownloadStockHistory(string symbol, CancellationToken token) //傳遞{ string stockUrl = CreateFinanceUrl(symbol); var request = await new HttpClient().GetAsync(stockUrl, token); // 傳遞給方法以得取消 return await request.Content.ReadAsStringAsync();}//cts.Cancel(); // 出發(fā)取消令牌

        或則使用CancellationToken來注冊回調

        CancellationTokenSource tokenSource = new CancellationTokenSource();CancellationToken token = tokenSource.Token;Task.Run(async ()=> {    var webClint = new WebClient();    token.Register(()=>webClint.CancelAsync());    var data = await webClint.DownloadDataTaskAsync(url);},token);


        在之前版本如果沒有async和await時,通過手動檢查取消,定期使用token.ThrowIfCancellationRequested方法檢查取消


        3.2 協(xié)作取消支持


        使用CancellationTokenSource可以輕松創(chuàng)建由多個其他令牌組成的合令牌。像下面所示有一個取消原因被觸發(fā)就執(zhí)行取消操作。

        CancellationTokenSource ctsOne = new CancellationTokenSource()CancellationTokenSource ctsTwo = new CancellationTokenSource();CancellationTokenSource ctsComposite =  CancellationTokenSource.CreateLinkedTokenSource(ctsOne.Token,ctsTwo.Token);CancellationToken token = ctsComposite.Token;


        字數(shù)有點超了哈,想要每個小片1k字左右的,剩下的異步重試,錯誤處理放在下小節(jié)吧。


            to be contiued!
        下集:任務異步模型下




        寫給普通:

        時間撲面而來,我們終將釋懷

        健康的活著,平靜的過著

        開心的笑著,適當?shù)拿χ?/span>



        瀏覽 55
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            俱乐部yin乱聚会小说 | 申鹤被扒开腿做同人漫画 | 日本一本二本在线 | 主人调教巨奴性奶牛少妇小说 | 色五月久久婷婷综合片丁香花 | 国产精品嫩草影院88av | 黑人大屌在线 | 成人精品无码四虎 | free性videos另类重口 | 色搞搞 |