Tienes 3 opciones:
- Utilice el método del controlador integrado (por ejemplo,
ForEachAsync
,ToListAsync
). - En C# 8.0 y superior, puede convertir el
IAsyncCursor
en unIAsyncEnumerable
y useawait foreach
o cualquier operador LINQ asíncrono. - Iterar sobre el
IAsyncCursor
.
Métodos de controlador integrado
El controlador tiene algunos métodos de extensión similares a LINQ para IAsyncCursor
, como AnyAsync
, ToListAsync
, etc. Para la iteración tiene ForEachAsync
:
var cursor = await client.ListDatabasesAsync();
await cursor.ForEachAsync(db => Console.WriteLine(db["name"]));
Convertir a IAsyncEnumerable
En C# 8.0 y superior, debe ser más agradable iterar con await foreach
(y use LINQ asíncrono). Esto requiere envolver el IAsyncCursor
en un IAsyncEnumerable
Puede hacerlo usted mismo, pero dado que es importante hacer bien algunas cosas críticas (como la cancelación y la eliminación), publiqué un paquete nuget:MongoAsyncEnumerableAdapter
var cursor = await client.ListDatabasesAsync();
await foreach (var db in cursor.ToAsyncEnumerable())
{
Console.WriteLine(db["name"]);
}
Iteración personalizada
La iteración tradicional en C# se realiza con IEnumerable
y foreach
. foreach
es el azúcar sintáctico del compilador. En realidad es una llamada a GetEnumerator
, un using
alcance y un while
bucle:
using (var enumerator = enumerable.GetEnumerator())
{
while (enumerator.MoveNext())
{
var current = enumerator.Current;
// use current.
}
}
IAsyncCursor
es equivalente a IEnumerator
(el resultado de IEnumerable.GetEnumerator
) mientras que IAsyncCursorSource
es a IEnumerable
. La diferencia es que estos admiten async
(y obtenga un lote en cada iteración y no solo un elemento). Entonces puedes implementar todo el using
, while
hacer un bucle tú mismo:
IAsyncCursorSource<int> cursorSource = null;
using (var asyncCursor = await cursorSource.ToCursorAsync())
{
while (await asyncCursor.MoveNextAsync())
{
foreach (var current in asyncCursor.Current)
{
// use current
}
}
}