首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异常发生时如何取消IAsyncEnumerable?

异常发生时如何取消IAsyncEnumerable?
EN

Stack Overflow用户
提问于 2022-06-10 02:15:09
回答 1查看 105关注 0票数 0

我使用IAsyncEnumerable来获取许多数据-如下所示:

代码语言:javascript
复制
static async IAsyncEnumerable<int> GetSequence([EnumeratorCancellation] CancellationToken ct = default)
{
    for (int i = 1; i <= 10; i++)
    {
        var data = await DoSomethingAsync()    // get data from web request
        yield return data;
    }
}

现在我的问题是:如果DoSomethingAsync抛出一个异常(可能是网络问题),我想取消其余的请求,这有可能吗?

我正在尝试处理下面的代码,但仍然需要帮助:

代码语言:javascript
复制
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;

try
{
    IAsyncEnumerable<int> dataCol = GetSequence(token);

    await foreach (var d in dataCol)
    {
        // do ...
    }
}
catch (Exception)
{
   source.Cancel(true);
   throw;
}

感激某人是否有最佳实践

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-10 05:43:48

从最初的语文提案

代码语言:javascript
复制
await foreach (var d in dataCol)
{
    // do ...
}

等于;

代码语言:javascript
复制
{
    E e = dataCol.GetAsyncEnumerator();
    try {
        while (await e.MoveNextAsync()) {
            var d = e.Current;
            // do ...
        }
    }
    finally {
        ... // Dispose e
    }
}

调用MoveNextAsync会导致GetSequence方法执行到下一个yield return,或者直到抛出未处理的异常为止。在下一次调用MoveNextAsync之前,该方法的执行将不会继续。GetSequenceawait foreach不是并行运行的,它们轮流在同一个异步任务中执行更多的代码。

如果DoSomethingAsync抛出异常

然后await e.MoveNextAsync()将重新抛出异常。然后,枚举器将被释放。然后,异常将向堆栈上流到下一个异常处理程序。

您不需要使用取消令牌来阻止GetSequence恢复执行。实际上,脱离await foreach循环也会中止执行,就好像yield return从未恢复过一样。如果有任何finally{}块,则会导致GetSequence方法中的任何块执行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72568429

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档