Lor*_*eno 2 c# .net-core iasyncenumerable
我需要IAsyncEnumerable将所有结果存储在某个数据库中,但我还需要对第一项进行一些特殊处理。我是这样做的:
var someAsyncEnumerable = GetSomeAsyncEnumerable(cancellationToken);
var firstValue = await someAsyncEnumerable.FirstOrDefaultAsync(cancellationToken);
if (firstValue is not null)
{
// log something about first value
await HandleItem(fitstValue);
}
await foreach(var value in someAsyncEnumerable.Skip(1).WithCancellation(cancellationToken))
{
await HandleItem(value);
}
private async Task HandleItem(Item item)
{
// store item in DB
}
Run Code Online (Sandbox Code Playgroud)
使用这样的代码我收到警告:
可能的多重枚举
我想知道,这只是一个在这种情况下我可以完全忽略的警告,还是我对可枚举的使用错误?
假设 myIAsyncEnumerable不应该被枚举两次,因为它效率低下,甚至会破坏。
我想知道,这只是一个在这种情况下我可以完全忽略的警告,还是我对可枚举的使用错误?
“错误”是一个很强烈的词——但它肯定会引起问题。您将结果枚举两次,这在某些情况下很好,但在其他情况下却有问题。
正如你所说:
假设我的 IAsyncEnumerable 不应该被枚举两次,因为它效率低下,甚至会破坏。
...那么是的,你有问题了。因为你绝对会触发枚举两次。
最好枚举一次序列,跟踪您是否正在查看第一个项目并采取相应的操作:
var someAsyncEnumerable = GetSomeAsyncEnumerable(cancellationToken);
bool first = true;
await foreach (var value in someAsyncEnumerable)
{
if (first)
{
// Special handling of value
...
// For subsequent loop iterations, skip this bit
first = false;
}
else
{
await HandleItem(value);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这里我假设您想要第一个项目的完全不同的路径。如果您实际上只是想事先做额外的工作,则不需要该else块:
var someAsyncEnumerable = GetSomeAsyncEnumerable(cancellationToken);
bool first = true;
await foreach (var value in someAsyncEnumerable)
{
if (first)
{
// Special handling of value
...
// For subsequent loop iterations, skip this bit
first = false;
}
// Regardless of whether this is the first iteration or not,
// handle the item.
await HandleItem(value);
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以foreach自己将循环扩展为MoveNext调用等,但这更容易出错。
| 归档时间: |
|
| 查看次数: |
168 次 |
| 最近记录: |