Asynchronous Streams In C# 8.0

In this article, we'll learn how to create and consume Asynchronous Streams in C#. Starting with C# 8.0 we can use streams asynchronously.

Starting with C# 8.0, you can create and consume streams asynchronously. Async streams rely on new interfaces introduced in .NET Standard 2.1 and implemented in .NET Core 3.0 to provide a natural programming model for asynchronous streaming data sources.
To use async streams, you’ll need to set up your machine to run .NET Core, including the C# 8.0 compiler. The C# 8 compiler is available starting with Visual Studio 2019 version 16.3 or .NET Core 3.0 SDK.
Let's Start!
A method that returns an asynchronous stream has three properties,
  1. It's declared with the async modifier.
  2. It returns anIAsyncEnumerable<T>.
  3. The method contains yield return statements to return successive elements in the asynchronous stream.
Consuming an asynchronous stream requires you to add the await keyword before the foreach keyword when you enumerate the elements of the stream. Adding the await keyword requires the method that enumerates the asynchronous stream to be declared with the async modifier and to return a type allowed for an async method. Typically that means returning a Task or Task<TResult>. It can also be a ValueTask or ValueTask<TResult>. A method can both consume and produce an asynchronous stream, which means it would return an IAsyncEnumerable<T>. The following code generates a sequence from 0 to 19, waiting 100 ms between generating each number:
  1. public static async IAsyncEnumerable<int> GenerateSequence()  
  2. {  
  3.     for (int i = 0; i < 100; i++)  
  4.     {  
  5.          await Task.Delay(100);  
  6.          yield return i;  
  7.     }  
  8. }  
You would enumerate the sequence using the await foreach statement.
  1. await foreach (var number in GenerateSequence())  
  2. {  
  3.     Console.WriteLine(number);  
  4. }  
I've created a new Console App for using async streams. Here is my complete program. 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Threading.Tasks;  
  5. namespace CSharp_8._0  
  6. {  
  7.     class Program  
  8.     {  
  9.         //Asynchrounous Streams  
  10.         public static async IAsyncEnumerable<int> GenerateSequence()  
  11.         {  
  12.             for (int i = 0; i < 100; i++)  
  13.             {  
  14.                 await Task.Delay(100);  
  15.                 yield return i;  
  16.             }  
  17.         }  
  18.         public static async Task PrintSequence()  
  19.         {  
  20.             await foreach (var number in GenerateSequence())  
  21.             {  
  22.                 Console.WriteLine(number);  
  23.             }  
  24.         }  
  25.         static void Main(string[] args)  
  26.         {  
  27.             PrintSequence().Wait();  
  28.         }  
  30.     }  
  31. }   
You can also access this example code at my GitHub repo.
You can try asynchronous streams yourself in more deeply by this tutorial on creating and consuming async streams.