Имате 3 възможности:
- Използвайте метода на вградения драйвер (напр.
ForEachAsync
,ToListAsync
). - На C# 8.0 и по-нови можете да конвертирате
IAsyncCursor
вIAsyncEnumerable
и използвайтеawait foreach
или всеки асинхронен LINQ оператор. - Повтаряне на
IAsyncCursor
.
Вградени методи на драйвер
Драйверът има някои подобни на LINQ методи за разширение за IAsyncCursor
, като AnyAsync
, ToListAsync
и т.н. За итерация има ForEachAsync
:
var cursor = await client.ListDatabasesAsync();
await cursor.ForEachAsync(db => Console.WriteLine(db["name"]));
Конвертиране в IAsyncEnumerable
На C# 8.0 и по-нови трябва да е по-приятно да се повтаря с await foreach
(и използвайте асинхронен LINQ). Това изисква обвиване на IAsyncCursor
в IAsyncEnumerable
.Можете да го направите сами, но тъй като е важно някои критични неща да бъдат правилни (като анулиране и изхвърляне), публикувах пакет nuget:MongoAsyncEnumerableAdapter
var cursor = await client.ListDatabasesAsync();
await foreach (var db in cursor.ToAsyncEnumerable())
{
Console.WriteLine(db["name"]);
}
Персонализирана итерация
Традиционната итерация в C# се извършва с IEnumerable
и foreach
. foreach
е синтактичната захар на компилатора. Това всъщност е извикване на GetEnumerator
, a using
обхват и while
цикъл:
using (var enumerator = enumerable.GetEnumerator())
{
while (enumerator.MoveNext())
{
var current = enumerator.Current;
// use current.
}
}
IAsyncCursor
е еквивалентен на IEnumerator
(резултатът от IEnumerable.GetEnumerator
), докато IAsyncCursorSource
е към IEnumerable
. Разликата е, че те поддържат async
(и получавайте партида за всяка итерация, а не само един елемент). Така че можете да приложите целия using
, while
завъртете нещо сами:
IAsyncCursorSource<int> cursorSource = null;
using (var asyncCursor = await cursorSource.ToCursorAsync())
{
while (await asyncCursor.MoveNextAsync())
{
foreach (var current in asyncCursor.Current)
{
// use current
}
}
}