I'm trying to get a list of all the databases in my server and ultimately print them out (i.e. use their names as string
s). With the previous version of the c# driver I could call the Server.GetDatabases()
, but that has been replaced with ListDatabasesAsync()
.
The return value is an IAsyncCursor<>
and I'm not sure what to do with it. How does one iterate through the list of databases (or anything) with such a cursor?
Short answer: use the ForEachAsync
extension method:
var cursor = await client.ListDatabasesAsync();
await cursor.ForEachAsync(db => Console.WriteLine(db["name"]));
Long answer: Traditional iteration in C# is done with IEnumerable
and foreach
. foreach
is the compiler's syntactic sugar. It's actually a call to GetEnumerator
, a using
scope and a while
loop. But that doesn't support asynchronous operations:
using (var enumerator = enumerable.GetEnumerator())
{
while (enumerator.MoveNext())
{
var current = enumerator.Current;
// use current.
}
}
IAsyncCursor
is equivalent to IEnumerator
(the result of IEnumerable.GetEnumerator
) while IAsyncCursorSource
is toIEnumerable
. The difference is that these support async
(and get a batch each iteration and not just a single item). You can't use foreach
as it's built for IEnumerable
but you can implement the whole using
, while
loop thing:
IAsyncCursorSource<int> cursorSource = null;
using (var asyncCursor = await cursorSource.ToCursorAsync())
{
while (await asyncCursor.MoveNextAsync())
{
foreach (var current in asyncCursor.Current)
{
// use current
}
}
}
However that's a lot of boilerplate so the driver adds extension methods for IAsyncCursor
like ForEachAsync
, ToListAsync
and so forth.
That covers most common use cases but for others you do still need to implement the iteration yourself.