Hai 3 opzioni:
- Utilizza il metodo del driver integrato (ad es.
ForEachAsync
,ToListAsync
). - Su C# 8.0 e versioni successive puoi convertire
IAsyncCursor
in unIAsyncEnumerable
e usaawait foreach
o qualsiasi operatore LINQ asincrono. - Esegui l'iterazione su
IAsyncCursor
.
Metodi driver integrati
Il driver ha alcuni metodi di estensione simili a LINQ per IAsyncCursor
, come AnyAsync
, ToListAsync
, ecc. Per l'iterazione ha ForEachAsync
:
var cursor = await client.ListDatabasesAsync();
await cursor.ForEachAsync(db => Console.WriteLine(db["name"]));
Conversione in IAsyncEnumerable
In C# 8.0 e versioni successive è necessario eseguire l'iterazione con await foreach
(e usa LINQ asincrono). Ciò richiede il wrapping di IAsyncCursor
in un IAsyncEnumerable
.Puoi farlo da solo, ma poiché è importante correggere alcune cose critiche (come la cancellazione e lo smaltimento) ho pubblicato un pacchetto nuget:MongoAsyncEnumerableAdapter
var cursor = await client.ListDatabasesAsync();
await foreach (var db in cursor.ToAsyncEnumerable())
{
Console.WriteLine(db["name"]);
}
Iterazione personalizzata
L'iterazione tradizionale in C# viene eseguita con IEnumerable
e foreach
. foreach
è lo zucchero sintattico del compilatore. In realtà è una chiamata a GetEnumerator
, un using
scope e un while
ciclo:
using (var enumerator = enumerable.GetEnumerator())
{
while (enumerator.MoveNext())
{
var current = enumerator.Current;
// use current.
}
}
IAsyncCursor
è equivalente a IEnumerator
(il risultato di IEnumerable.GetEnumerator
) mentre IAsyncCursorSource
è IEnumerable
. La differenza è che supportano async
(e ottieni un batch ogni iterazione e non solo un singolo elemento). Quindi puoi implementare l'intero using
, while
fai il loop da solo:
IAsyncCursorSource<int> cursorSource = null;
using (var asyncCursor = await cursorSource.ToCursorAsync())
{
while (await asyncCursor.MoveNextAsync())
{
foreach (var current in asyncCursor.Current)
{
// use current
}
}
}