簡體   English   中英

我怎樣才能“適應”一個任務<ienumerable<t> &gt; 到 IAsyncEnumerable<t> ? </t></ienumerable<t>

[英]How can I "adapt" a Task<IEnumerable<T>> to IAsyncEnumerable<T>?

我正在逐步將 Ix.NET 引入到遺留項目中。 我有許多返回Task<IEnumerable<T>>的存儲級 API,但我想將它們調整為IAsyncEnumerable<T>以便在系統的 rest 中使用。 似乎應該有一個輔助方法(用於 IEnumerable 的ala .ToAsyncEnumerable() )來幫助解決這個問題,但我找不到任何東西......我必須實現自己的自定義枚舉器嗎? (不難,但我不想重新發明輪子)

Task<IEnumerable<T>> GetSomeResults<T>()
{
    throw new NotImplementedException();
}

async IAsyncEnumerable<T> GetAsyncEnumerable<T>()
{
    var results = await GetSomeResults<T>();
    foreach(var item in results)
    {
        yield return item;
    }
}

我一直在尋找完全相同的東西,由於這里的回復,我認為確實沒有像AsAsyncEnumerable()這樣的方法。 所以這就是我最終做的事情,也許它對其他人有幫助:

public static class AsyncEnumerableExtensions {
    public struct AsyncEnumerable<T> : IAsyncEnumerable<T> {
        private readonly IEnumerable<T> enumerable;

        public AsyncEnumerable(IEnumerable<T> enumerable) {
            this.enumerable = enumerable;
        }

        public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = new CancellationToken()) {
            return new AsyncEnumerator<T>(enumerable?.GetEnumerator());
        }
    }

    public struct AsyncEnumerator<T> : IAsyncEnumerator<T> {
        private readonly IEnumerator<T> enumerator;

        public AsyncEnumerator(IEnumerator<T> enumerator) {
            this.enumerator = enumerator;
        }

        public ValueTask DisposeAsync() {
            enumerator?.Dispose();
            return default;
        }

        public ValueTask<bool> MoveNextAsync() {
            return new ValueTask<bool>(enumerator == null ? false : enumerator.MoveNext());
        }

        public T Current => enumerator.Current;
    }

    public static AsyncEnumerable<T> AsAsyncEnumerable<T>(this IEnumerable<T> that) {
        return new AsyncEnumerable<T>(that);
    }

    public static AsyncEnumerator<T> AsAsyncEnumerator<T>(this IEnumerator<T> that) {
        return new AsyncEnumerator<T>(that);
    }
}

如果您在談論 Web API,那么Task<IEnumerable<T>>是一種生成IEnumerable<T>的異步方式。

無論IEnumerable<T>是同步生成還是異步生成,整個列表都將作為 HTTP 響應發送。

您可以在客戶端上利用IAsyncEnumerable<T>的方式是該客戶端是否正在調用某種流或向服務器發出多個請求以獲得唯一的結果列表(分頁)。

As commented by Theodor Zoulias , System.Linq.Async is a NuGet package from .NET Foundation , which supports ToAsyncEnumerable() .

示例用法:

    var tasks = new Task[0]; // get your IEnumerable<Task>s
    tasks.ToAsyncEnumerable();
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(this IEnumerable<T> enumerable)
{
    using IEnumerator<T> enumerator = enumerable.GetEnumerator();

    while (await Task.Run(enumerator.MoveNext).ConfigureAwait(false))
    {
        yield return enumerator.Current;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM