我有一个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
}

使用这样的代码,我收到了一个警告:

可能的多重枚举

我想知道,在这种情况下,这只是一个我可以完全忽略的警告,还是我对可枚举数的使用是错误的?

让我们假设我的IAsyncEnumerable不应该被枚举两次,因为它的效率很低,甚至是崩溃.

推荐答案

我想知道,在这种情况下,这只是一个我可以完全忽略的警告,还是我对可枚举数的使用是错误的?

"错误"是一个很强烈的词--但它肯定会带来问题.您列举了两次结果,这在某些情况下很好,但在其他情况下就有问题了.

正如你所说:

让我们假设我的IAsyncEnumerable不应该被枚举两次,因为它的效率很低,甚至会中断.

...那么,是的,你有麻烦了.因为你绝对are触发两次枚举.

最好是列举一次序列,跟踪您是否正在查看第一个项目,并相应地执行操作:

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);    
   }
}

请注意,在这里,我假设您希望第一个项目有一个完全不同的路径.如果你真的只想事先做extra项工作,你不需要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);    
}

或者,您可以自己将foreach循环扩展为MoveNext个调用等,但这更容易出错.

Csharp相关问答推荐

将实例绑定方法传递到列表foreach

Microsoft.AspNetCore.Mvc. Controller Base.用户:属性或索引器Controller Base.用户无法分配给--它是只读的

有没有方法让ASP.NET Core模型绑定器使用私有设置器来设置属性?

在依赖性注入和继承之间进行 Select

CsWin32如何创建PWSTR的实例,例如GetWindowText

如何使用C#和Graph API从Azure Directory获取用户详细信息

将委托传递到serviceccollection c#web API

一种安全的方式来存储SSH凭证(MAUI/C#应用程序)

ASP.NET配置kestrel以使用Windows证书存储中的HTTPS

Unix上的.NET(核心):.NET意外地未看到通过P/Invoke系统调用对环境变量进行的进程内修改

在不添加不必要的尾随零的情况下本地化浮点型?

有空容错运算符的对立面吗?

如何比较C#中的L和ł(波兰字符)返回TRUE

BFF到具有AAD/Entra ID B2C的内部API(.NET/ASP.NET核心/标识.Web)

使用CollectionView时在.NET Maui中显示数据时出现问题

在C#ASP.NET内核中使用INT AS-1进行控制器场景的单元测试

从GRPC连接创建ZipArchive

为什么在使用JsonDerivedType序列化泛型时缺少$type?

如何从SignalR获取连接客户端的域

Azure队列触发器未使用隔离的工作进程执行