Nell versioni precedenti di C# era già presente il supporto a iteratori e metodi asincroni. Una delle novità, molto utili, presenti in C# 8.0 è la combinazione dei due, per la creazione di streams asincroni. Questa funzioanalità è possibile, perchè sono state introdotte le versioni asincrone delle interfacce IEnumerable e IEnumerator :
public interface IAsyncEnumerable<out T>{IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = default);} public interface IAsyncEnumerator<out T> : IAsyncDisposable{T Current { get; } ValueTask<bool> MoveNextAsync();} |
In aggiunta è stata introdotta una versione asincrona anche per l’interfaccia IDisposable per poter utilizzare in maniera asincrona gli iteratori:
public interface IAsyncDisposable{ValueTask DisposeAsync();} |
E’ quindi possibile scrivere il seguente codice:
var asyncEnumerator = GetValuesAsync().GetAsyncEnumerator();try {while (await asyncEnumerator.MoveNextAsync()){var value = asyncEnumerator.Current; // process value} }finally {await asyncEnumerator.DisposeAsync();} |
dove il codice, anche se asincrono, assume una forma compatta e simile a quello sincrona. Nella programmazione di tutti i giorni, si fa uno dell’operatore foreach, con cui normalmente si ha maggiore famigliariarità . E’ possibile utilizzare una versione asincrona dell’operatore foreach, che fa uso degli operatore asincroni:
await foreach (var value in GetValuesAsync()){// process value} |