Você tem 3 opções:
- Use o método de driver integrado (por exemplo,
ForEachAsync
,ToListAsync
). - No C# 8.0 e acima, você pode converter o
IAsyncCursor
em umIAsyncEnumerable
e useawait foreach
ou qualquer operador LINQ assíncrono. - Iterar sobre o
IAsyncCursor
.
Métodos de driver integrados
O driver tem alguns métodos de extensão do tipo LINQ para
IAsyncCursor
, como AnyAsync
, ToListAsync
, etc. Para iteração, tem ForEachAsync
:var cursor = await client.ListDatabasesAsync();
await cursor.ForEachAsync(db => Console.WriteLine(db["name"]));
Convertendo para IAsyncEnumerable
No C# 8.0 e acima, é melhor iterar com
await foreach
(e use LINQ assíncrono). Isso requer envolver o IAsyncCursor
em um IAsyncEnumerable
.Você pode fazer isso sozinho, mas como é importante acertar algumas coisas importantes (como cancelamento e descarte), publiquei um pacote de nuget:MongoAsyncEnumerableAdapter
var cursor = await client.ListDatabasesAsync();
await foreach (var db in cursor.ToAsyncEnumerable())
{
Console.WriteLine(db["name"]);
}
Iteração personalizada
A iteração tradicional em C# é feita com
IEnumerable
e foreach
. foreach
é o açúcar sintático do compilador. Na verdade, é uma chamada para GetEnumerator
, um using
escopo e um while
ciclo:using (var enumerator = enumerable.GetEnumerator())
{
while (enumerator.MoveNext())
{
var current = enumerator.Current;
// use current.
}
}
IAsyncCursor
é equivalente a IEnumerator
(o resultado de IEnumerable.GetEnumerator
) enquanto IAsyncCursorSource
é para IEnumerable
. A diferença é que eles suportam async
(e obtenha um lote a cada iteração e não apenas um único item). Então você pode implementar todo o using
, while
coisa de loop você mesmo:IAsyncCursorSource<int> cursorSource = null;
using (var asyncCursor = await cursorSource.ToCursorAsync())
{
while (await asyncCursor.MoveNextAsync())
{
foreach (var current in asyncCursor.Current)
{
// use current
}
}
}