Async Streams in C#
Tamir Dresher
Twitter: @tamir_dresher
2
System Architect @ @tamir_dresher
Tamir Dresher
My Books:
Software Engineering Lecturer
Ruppin Academic Center https://www.israelclouds.com/iasaisrael
https://tinyurl.com/Telescopim-YouTube
Async work in C#
.NET 2.0
- Event Asynchronous
Pattern
(Async method + event)
.NET 1.1
Asynchronous Programming Model
(Begin/End Methods)
.NET 4.5
Task Asynchronous
Pattern
C# 7.0
Async Main
C# 5.0
Async Await
C# 8
- Async Streams
- Async Disposables
Single
Value
• IObservable<T> , IObserver<T>
• Reactive Extensions (Rx)
Async Stream
g(x)
f(x)
Demo
IEnumerable and Iterators
SharpLab Demo
Sync over Async
Avoid Exposing Synchronous Wrappers for Asynchronous Implementations
Sync over async will lead to ThreadPool starvation on high load
Thread Pool
Thread
Request
Async IO
Thread
IAsyncEnumerable
namespace System.Collections.Generic
{
public interface IAsyncEnumerable<out T>
{
IAsyncEnumerator<T> GetAsyncEnumerator(
CancellationToken cancellationToken = default);
}
public interface IAsyncEnumerator<out T> : IAsyncDisposable
{
ValueTask<bool> MoveNextAsync();
T Current { get; }
}
}
SharpLab
namespace System
{
public interface IAsyncDisposable
{
ValueTask DisposeAsync();
}
}
namespace System.Collections.Generic
{
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T> : IDisposable,
IEnumerator
{
bool MoveNext ();
T Current { get; }
}
}
Async stream example
public static async Task Main()
{
var records = ReadLines("transactions.csv");
await foreach (var record in records)
{
Console.WriteLine($"Transaction from {record[0]} to {record[1]}");
}
}
public static async IAsyncEnumerable<string[]> ReadLines(string path)
{
var lines = await System.IO.File.ReadAllLinesAsync(path);
foreach (var line in lines)
{
yield return line.Split(',');
}
}
Summary
Single Value Multiple Value
Sync T IEnumerable<T>
Async Task<T> IAsyncEnumerable<T>
IObservable<T>
Avoid as much as possible Sync-Over-Async
Cancellation - Mark the CancelleationToken parameter with EnumeratorCancellation
attribute and use the WithCancellation() extension method propagate the token
Use the System.Linq.Async and System.Interactive.Async NuGet packages to add async
LINQ operators
@tamir_dresher

Tamir Dresher - Async Streams in C#

  • 1.
    Async Streams inC# Tamir Dresher Twitter: @tamir_dresher
  • 2.
    2 System Architect @@tamir_dresher Tamir Dresher My Books: Software Engineering Lecturer Ruppin Academic Center https://www.israelclouds.com/iasaisrael https://tinyurl.com/Telescopim-YouTube
  • 3.
    Async work inC# .NET 2.0 - Event Asynchronous Pattern (Async method + event) .NET 1.1 Asynchronous Programming Model (Begin/End Methods) .NET 4.5 Task Asynchronous Pattern C# 7.0 Async Main C# 5.0 Async Await C# 8 - Async Streams - Async Disposables Single Value • IObservable<T> , IObserver<T> • Reactive Extensions (Rx)
  • 4.
  • 5.
  • 6.
    Sync over Async AvoidExposing Synchronous Wrappers for Asynchronous Implementations Sync over async will lead to ThreadPool starvation on high load Thread Pool Thread Request Async IO Thread
  • 7.
    IAsyncEnumerable namespace System.Collections.Generic { public interfaceIAsyncEnumerable<out T> { IAsyncEnumerator<T> GetAsyncEnumerator( CancellationToken cancellationToken = default); } public interface IAsyncEnumerator<out T> : IAsyncDisposable { ValueTask<bool> MoveNextAsync(); T Current { get; } } } SharpLab namespace System { public interface IAsyncDisposable { ValueTask DisposeAsync(); } } namespace System.Collections.Generic { public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); } public interface IEnumerator<out T> : IDisposable, IEnumerator { bool MoveNext (); T Current { get; } } }
  • 8.
    Async stream example publicstatic async Task Main() { var records = ReadLines("transactions.csv"); await foreach (var record in records) { Console.WriteLine($"Transaction from {record[0]} to {record[1]}"); } } public static async IAsyncEnumerable<string[]> ReadLines(string path) { var lines = await System.IO.File.ReadAllLinesAsync(path); foreach (var line in lines) { yield return line.Split(','); } }
  • 9.
    Summary Single Value MultipleValue Sync T IEnumerable<T> Async Task<T> IAsyncEnumerable<T> IObservable<T> Avoid as much as possible Sync-Over-Async Cancellation - Mark the CancelleationToken parameter with EnumeratorCancellation attribute and use the WithCancellation() extension method propagate the token Use the System.Linq.Async and System.Interactive.Async NuGet packages to add async LINQ operators @tamir_dresher