programing

iAsyncCursor는 mongodbc# 드라이버와의 반복에 어떻게 사용됩니까?

newsource 2023. 6. 29. 20:11

iAsyncCursor는 mongodbc# 드라이버와의 반복에 어떻게 사용됩니까?

서버에 있는 모든 데이터베이스의 목록을 가져와서 최종적으로 출력하려고 합니다(즉, 이름을 다음과 같이 사용).string. 이전 버전의 c# 드라이버로 저는 전화를 걸 수 있었습니다.Server.GetDatabases()하지만 그것은 대체되었습니다.ListDatabasesAsync().

반환 값은 다음과 같습니다.IAsyncCursor<>어떻게 해야 할지 모르겠어요이러한 커서를 사용하여 데이터베이스(또는 기타) 목록을 어떻게 반복합니까?

세 가지 옵션이 있습니다.

  1. 기본 제공 드라이버 방법을 사용합니다(예:ForEachAsync,ToListAsync).
  2. C# 8.0 이상에서는 다음을 변환할 수 있습니다.IAsyncCursor의 상태로.IAsyncEnumerable및 사용await foreach또는 임의의 비동기 LINQ 연산자.
  3. 를 반복합니다.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직접 할 수 있지만 취소 및 폐기와 같은 몇 가지 중요한 사항을 올바르게 처리하는 것이 중요하기 때문에 다음과 같은 너겟 패키지를 게시했습니다.MongoAsync 열거형 어댑터

var cursor = await client.ListDatabasesAsync();
await foreach (var db in cursor.ToAsyncEnumerable())
{
    Console.WriteLine(db["name"]);
}
사용자 정의 반복

C#의 기존 반복은 다음을 통해 수행됩니다.IEnumerable그리고.foreach.foreach컴파일러의 구문 당입니다.사실은 하기 위한 전화입니다.GetEnumerator,ausing범위와 awhile루프:

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
        }
    }
}

저는 개인적으로 커서를 C#8로 변환하는 것을 좋아합니다.IAsyncEnumerable그런 식으로 열거형 작업의 모든 이점을 얻을 수 있습니다(LINQ주로)

@i3arnon의 "긴 답변"을 사용하여 다음 확장 방법을 만들었습니다.

public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(this IAsyncCursor<T> asyncCursor)
{
    while (await asyncCursor.MoveNextAsync())
    {
        foreach (var current in asyncCursor.Current)
        {
            yield return current;
        }
    }
}

다음에 대한 확장 방법 지원 덕분입니다.GetAsyncEnumeratorC# 9 및 오리형 구현에서foreach이제 다음 확장 방법을 사용하여 커서를 직접 반복할 수 있습니다.

public static class MongoDbCursorExtensions
{
    public static IAsyncCursor<T> GetAsyncEnumerator<T>(this IAsyncCursor<T> cursor) => cursor;
}

용도:

var cursor = await collection.Find(filter).ToCursorAsync();
await foreach (var batch in cursor) // extension method implicitly called here
{
    foreach (var item in batch)
    {
        // ...
    }
}

참조: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/iteration-statements#the-foreach-statement

언급URL : https://stackoverflow.com/questions/29682371/how-is-an-iasynccursor-used-for-iteration-with-the-mongodb-c-sharp-driver