使用 aCancellationToken
是解决方案,因为这是唯一可以取消Task.Delay
代码中的东西。我们在你的内部获取它的方式IAsyncEnumerable
是在创建它时将它作为参数传递,所以让我们这样做:
public async IAsyncEnumerable<int> EnumerateAsync(CancellationToken cancellationToken = default) {
for (int i = 0; i < 10; i++) {
yield return i;
await Task.Delay(1000, cancellationToken);
}
}
消费方面:
// In this example the cancellation token will be caneled after 2.5 seconds
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2.5));
await foreach (var item in EnumerateAsync(cts.Token)) {
Console.WriteLine(item);
}
当然,这将在返回 3 个元素后取消枚举,但会以TaskCanceledException
throw out of结束Task.Delay
。为了优雅地退出,await foreach
我们必须抓住它并在生产端中断:
public async IAsyncEnumerable<int> EnumerateAsync(CancellationToken cancellationToken = default) {
for (int i = 0; i < 10; i++) {
yield return i;
try {
await Task.Delay(1000, cancellationToken);
} catch (TaskCanceledException) {
yield break;
}
}
}
笔记
截至目前,这仍处于预览阶段,可能会发生变化。如果您对此主题感兴趣,可以观看C# 语言团队关于CancellationToken
.IAsyncEnumeration