我正在尝试找出IAsyncEnumerable<T>
带来类似IEnumerable<Task<T>>
.
我编写了以下类,它允许我等待一系列数字,每个数字之间都有定义的延迟:
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();
}
这个类同时实现IAsyncEnumerable<int>
和IEnumerable<Task<int>>
。我可以同时使用它来迭代它await foreach
并foreach
获得相同的结果:
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);
}
两次迭代都显示数字 0 到 4,每行之间有一秒的延迟。
唯一的优势与取消能力(即传入cancellationToken
)有关吗?还是有一些我在这里看不到的场景?