简体   繁体   English

IAsyncEnumerable 和有什么区别<t>和一个迭代器生成的 IEnumerable <task<t> &gt;? </task<t></t>

[英]What's the difference between IAsyncEnumerable<T> and an iterator-generated IEnumerable<Task<T>>?

I'm trying to work out the advantage that IAsyncEnumerable<T> brings over something like an IEnumerable<Task<T>> .我正在尝试找出IAsyncEnumerable<T>带来的优势,例如IEnumerable<Task<T>>

I wrote the following class that allows me to wait for a sequence of numbers with a defined delay between each one:我写了以下 class ,它允许我等待一系列数字,每个数字之间都有定义的延迟:

class DelayedSequence : IAsyncEnumerable<int>, IEnumerable<Task<int>> {
    readonly int _numDelays;
    readonly TimeSpan _interDelayTime;

    public DelayedSequence(int numDelays, TimeSpan interDelayTime) {
        _numDelays = numDelays;
        _interDelayTime = interDelayTime;
    }

    public IAsyncEnumerator<int> GetAsyncEnumerator(CancellationToken cancellationToken = default) {
        async IAsyncEnumerable<int> ConstructEnumerable() {
            for (var i = 0; i < _numDelays; ++i) {
                await Task.Delay(_interDelayTime, cancellationToken);
                yield return i;
            }
        }

        return ConstructEnumerable().GetAsyncEnumerator();
    }

    public IEnumerator<Task<int>> GetEnumerator() {
        IEnumerable<Task<int>> ConstructEnumerable() {
            for (var i = 0; i < _numDelays; ++i) {
                yield return Task.Delay(_interDelayTime).ContinueWith(_ => i);
            }
        }

        return ConstructEnumerable().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

This class implements both IAsyncEnumerable<int> and IEnumerable<Task<int>> .这个 class 实现了IAsyncEnumerable<int>IEnumerable<Task<int>> I can iterate over it using both await foreach and foreach and get an identical result:我可以同时使用await foreachforeach对其进行迭代并获得相同的结果:

var delayedSequence = new DelayedSequence(5, TimeSpan.FromSeconds(1d));

await foreach (var i in delayedSequence) {
    Console.WriteLine(i);
}

foreach (var t in delayedSequence) {
    Console.WriteLine(await t);
}

Both iterations display the numbers 0 to 4 with a second's delay between each line.两次迭代都显示数字 0 到 4,每行之间有一秒的延迟。

Is the only advantage relating to the ability to cancel (ie the passed-in cancellationToken )?唯一的优势是与取消能力有关吗(即传入的cancellationToken )? Or is there some scenario I'm not seeing here?还是有一些我在这里看不到的场景?

wait for a sequence of numbers with a defined delay between each one等待一系列数字,每个数字之间有定义的延迟

The delay happens at different times.延迟发生在不同的时间。 IEnumerable<Task<T>> immediately returns the next element, which is then await ed. IEnumerable<Task<T>>立即返回下一个元素,然后是await ed。 IAsyncEnumerable<T> await s the next element. IAsyncEnumerable<T> await下一个元素。

IEnumerable<Task<T>> is a (synchronous) enumeration where each element is asynchronous. IEnumerable<Task<T>>是一个(同步)枚举,其中每个元素都是异步的。 This is the proper type to use when you have a known number of actions to perform and then each item asynchronously arrives independently.当您要执行已知数量的操作并且每个项目独立异步到达时,这是使用的正确类型。

For example, this type is commonly used when sending out multiple REST requests simultaneously.例如,这种类型通常用于同时发送多个 REST 请求时。 The number of REST requests to make is known at the start, and each request is Select ed into an asynchronous REST call. REST 请求的数量在开始时是已知的,每个请求都被Select编入异步 REST 调用。 The resulting enumerable (or collection) is then usually passed to await Task.WhenAll to asynchronously wait for them all to complete.然后通常将生成的可枚举(或集合)传递给await Task.WhenAll以异步等待它们全部完成。

IAsyncEnumerable<T> is an asynchronous enumeration; IAsyncEnumerable<T>是一个异步枚举; ie, its MoveNext is actually an asynchronous MoveNextAsync .即, 它的MoveNext实际上是一个异步MoveNextAsync This is the proper type to use when you have an unknown number of items to iterate, and getting the next (or next batch) is (potentially) asynchronous.当您有未知数量的要迭代的项目并且获取下一个(或下一批)是(可能)异步时,这是使用的正确类型。

For example, this type is commonly used when paging results from an API.例如,这种类型通常在来自 API 的分页结果时使用。 In this case, you have no idea how many elements will eventually be returned.在这种情况下,您不知道最终将返回多少个元素。 In fact, you may not even know if you are at the end until after retrieving the next page of results.事实上,在检索到下一页结果之前,您甚至可能都不知道自己是否已经结束。 So even determining whether there is a next item is an asynchronous operation.所以即使判断是否有下一项也是异步操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 IAsyncEnumerable 有什么区别<T>与 IEnumerable <Task<T> &gt;? - Whats the difference between IAsyncEnumerable<T> vs IEnumerable<Task<T>>? 我应该选择 IAsyncEnumerable<T> 或 IEnumerable <Task<T> &gt;? - should i choose IAsyncEnumerable<T> or IEnumerable<Task<T>>? 我怎样才能“适应”一个任务<ienumerable<t> &gt; 到 IAsyncEnumerable<t> ? </t></ienumerable<t> - How can I "adapt" a Task<IEnumerable<T>> to IAsyncEnumerable<T>? 异步迭代器任务<IEnumerable<T> &gt; - Asynchronous iterator Task<IEnumerable<T>> 返回IEnumerable的迭代器方法之间有什么区别吗? <T> 和IEnumerator <T> ? - Is there any difference between iterator methods returning IEnumerable<T> and IEnumerator<T>? ((IEnumerable)source).OfType有什么区别 <T> ()和源为IEnumerable <T> - What is the difference between ((IEnumerable)source).OfType<T>() and source as IEnumerable<T> 在实现迭代器时,返回IEnumerator或IEnumerable之间有什么区别? - when implementing iterator, what's the difference between returning IEnumerator or IEnumerable? IEnumerable和IEnumerable <T>之间的区别? - Difference between IEnumerable and IEnumerable<T>? 非泛型 IEnumerable 和泛型 IEnumerable 有什么区别<T> ? - What is the difference between the non-generic IEnumerable and the generic IEnumerable<T>? “此IEnumerable”和“ <T> 项目”和“此T项目”? - What is the difference between “this IEnumerable<T> items” and “this T items”?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM