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
IAsyncCursorem umIAsyncEnumerablee useawait foreachou 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
}
}
}