日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
如何在 C# 8 中使用 異步流

本文轉(zhuǎn)載自微信公眾號(hào)「碼農(nóng)讀書(shū)」,作者碼農(nóng)讀書(shū)。轉(zhuǎn)載本文請(qǐng)聯(lián)系碼農(nóng)讀書(shū)公眾號(hào)。

異步編程已經(jīng)流行很多年了,.NET 引入的 async 和 await 關(guān)鍵詞讓異步編程更具有可讀性,但有一個(gè)遺憾,在 C# 8 之前都不能使用異步的方式處理數(shù)據(jù)流,直到 C# 8 引入的 IAsyncEnumerable 才解決了這個(gè)問(wèn)題。

說(shuō)到 IAsyncEnumerable ,得先說(shuō)一說(shuō) IEnumerable ,大家都知道,它是用同步的方式來(lái)迭代 collection 集合的,而這里的 IAsyncEnumerable 則是用異步方式,換句話說(shuō):IAsyncEnumerable 在迭代集合的過(guò)程中不會(huì)阻塞調(diào)用線程。

IAsyncDisposable, IAsyncEnumerable,  IAsyncEnumerator

異步流 允許我們可以用異步的方式處理數(shù)據(jù),在這之前要了解下面三個(gè)接口:IAsyncDisposable, IAsyncEnumerable 和 IAsyncEnumerator,他們都是在 .NET Standard 2.1 中被引入,下面的代碼片段展示了這三個(gè)接口的定義。

 
 
 
 
  1. public interface IAsyncDisposable 
  2.     ValueTask DisposeAsync(); 
  3.  
  4. public interface IAsyncEnumerable 
  5.     IAsyncEnumerator GetAsyncEnumerator(CancellationToken 
  6.     token = default); 
  7.  
  8. public interface IAsyncEnumerator : IAsyncDisposable 
  9.     ValueTask MoveNextAsync(); 
  10.     T Current { get; } 

為什么要使用異步流

可以想象一下你有一個(gè)數(shù)據(jù)訪問(wèn)層需要從數(shù)據(jù)庫(kù)中一次性讀取所有的數(shù)據(jù),要想使用這個(gè)功能很簡(jiǎn)單,可以直接調(diào)用 底層提供的異步方法 XXXAsyc 實(shí)現(xiàn)異步調(diào)用并且一次性返回所有數(shù)據(jù)。

只要不是將所有數(shù)據(jù)都呈現(xiàn)在頁(yè)面上的話,這種解決方案問(wèn)題不是太大,很多時(shí)候更多的是通過(guò) 分頁(yè)讀取 的形式,其實(shí)在這方面還有一個(gè)比較好的做法就是在數(shù)據(jù)可用時(shí)立即返回給調(diào)用者。

準(zhǔn)確的說(shuō),這里可使用 異步流 的方式來(lái)解決,如果你的方法是同步返回的話,你可以使用 return yield + 返回值 IEnumerable 模式,很遺憾的是,這種方式?jīng)]有擴(kuò)展性,因?yàn)樗切枰枞{(diào)用線程的。

最好的解決方案就是 return yield + 返回值 IAsyncEnumerable 模式,異步流方法返回的是 IAsyncEnumerable 實(shí)例,并且可以包含一個(gè)或多個(gè) yield return 語(yǔ)句。

在 C#8 中創(chuàng)建異步流

下面的代碼片段展示了一個(gè)返回 Task

 
 
 
 
  1. class Program 
  2.  { 
  3.      const int DELAY = 1000; 
  4.      const int MIN = 1; 
  5.      const int MAX = 10; 
  6.  
  7.      public static async Task Main(string[] args) 
  8.      { 
  9.          foreach (int number in await GetData()) 
  10.          { 
  11.              Console.WriteLine($"{DateTime.Now}: number={number}"); 
  12.          } 
  13.  
  14.          Console.ReadLine(); 
  15.      } 
  16.  
  17.      public static async Task> GetData() 
  18.      { 
  19.          List integers = new List(); 
  20.          for (int i = MIN; i <= MAX; i++) 
  21.          { 
  22.              await Task.Delay(DELAY); 
  23.              integers.Add(i); 
  24.          } 
  25.          return integers; 
  26.      } 
  27.  } 

當(dāng)運(yùn)行上面的應(yīng)用程序,它會(huì)等待 10s 之后再將所有的 1-10 的數(shù)字輸出控制臺(tái)上,雖然這個(gè) GetData 是異步的,但最終還是一次性輸出了,而不是一個(gè)一個(gè)的隔秒輸出。

這個(gè)時(shí)候可以讓 yield 關(guān)鍵詞介入,它是在 C# 2.0 中被引入的,常用于執(zhí)行狀態(tài)迭代 并且按一個(gè)一個(gè)的從集合中返回?cái)?shù)據(jù),你不需要像上面一樣創(chuàng)建一個(gè)集合(integers) 再返回上去,下面的代碼片段是修改 GetData 方法并且合并了 yield 關(guān)鍵詞的版本,代碼如下:

 
 
 
 
  1. static async IAsyncEnumerable GetData() 
  2.    for (int i = MIN; i < MAX; i++) 
  3.    { 
  4.       yield return i; 
  5.       await Task.Delay(DELAY);   
  6.    } 

C#8 中使用異步流

要想使用異步流, 需要在 foreach 前增加一個(gè) await 關(guān)鍵詞,如下代碼所示:

 
 
 
 
  1. public static async Task Main(string[] args) 
  2.         { 
  3.             await foreach (int number in GetData()) 
  4.             { 
  5.                 Console.WriteLine($"{DateTime.Now}: number={number}"); 
  6.             } 
  7.  
  8.             Console.ReadLine(); 
  9.         } 

下面是完整的僅供參考的代碼。

 
 
 
 
  1. class Program 
  2.    { 
  3.        const int DELAY = 1000; 
  4.        const int MIN = 1; 
  5.        const int MAX = 10; 
  6.  
  7.        public static async Task Main(string[] args) 
  8.        { 
  9.            await foreach (int number in GetData()) 
  10.            { 
  11.                Console.WriteLine($"{DateTime.Now}: number={number}"); 
  12.            } 
  13.  
  14.            Console.ReadLine(); 
  15.        } 
  16.  
  17.        static async IAsyncEnumerable GetData() 
  18.        { 
  19.            for (int i = MIN; i < MAX; i++) 
  20.            { 
  21.                yield return i; 
  22.                await Task.Delay(DELAY); 
  23.            } 
  24.        } 
  25.    } 

C# 8 中一個(gè)非常重要的特性就是支持了 IAsyncEnumerable ,它可以讓你應(yīng)用程序代碼更干凈,更高效 和 更高性能。

譯文鏈接:https://www.infoworld.com/article/3531251/how-to-use-asynchronous-streams-in-csharp-80.html


本文名稱:如何在 C# 8 中使用 異步流
網(wǎng)址分享:http://www.dlmjj.cn/article/cdshocs.html