我使用IAsyncEnumerable来获取许多数据-如下所示:
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抛出一个异常(可能是网络问题),我想取消其余的请求,这有可能吗?
我正在尝试处理下面的代码,但仍然需要帮助:
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;
}感激某人是否有最佳实践
发布于 2022-06-10 05:43:48
从最初的语文提案
await foreach (var d in dataCol)
{
// do ...
}等于;
{
E e = dataCol.GetAsyncEnumerator();
try {
while (await e.MoveNextAsync()) {
var d = e.Current;
// do ...
}
}
finally {
... // Dispose e
}
}调用MoveNextAsync会导致GetSequence方法执行到下一个yield return,或者直到抛出未处理的异常为止。在下一次调用MoveNextAsync之前,该方法的执行将不会继续。GetSequence和await foreach不是并行运行的,它们轮流在同一个异步任务中执行更多的代码。
如果DoSomethingAsync抛出异常
然后await e.MoveNextAsync()将重新抛出异常。然后,枚举器将被释放。然后,异常将向堆栈上流到下一个异常处理程序。
您不需要使用取消令牌来阻止GetSequence恢复执行。实际上,脱离await foreach循环也会中止执行,就好像yield return从未恢复过一样。如果有任何finally{}块,则会导致GetSequence方法中的任何块执行。
https://stackoverflow.com/questions/72568429
复制相似问题