.net Channels:为什么生产者输出在无界通道中被 consumer/reader 一个接一个地消费

.net Channels : Why producer output is consumed serially one after the other by the consumer/reader in an unbounded channel

主程序启动一个任务,该任务是Channel 的消费者任务。消费者任务代码是:

while (await channelReader.WaitToReadAsync())
            {
                while(channelReader.TryRead(out item))
                {
                    console.writeline("item is"+item.clientId);
                }
            }

有套接字服务器。当套接字客户端连接到服务器时,服务器为每个客户端启动任务。每个客户端任务都是通道的生产者。 生产者代码是:

foreach (var item in itemList )
{
     item.clientId = clientId;        
     await drawChannelWriter.WriteAsync(item);
}

发生的情况是:首先接收来自一个客户端的所有元素,然后接收来自其他任务的所有元素。 为什么频道里没有混合来自不同任务的不同元素?

Channels 是一个高性能的异步就绪 producer/consumer 队列。 “高性能”位意味着它将尽可能同步完成。

When socket client connects to server, server starts task for each client. Each client task is a producer for the channel.

这很好。我要检查的第一件事是每个客户端是否 运行 正在单独的 线程 (例如,Task.Run),或者它们是否只是异步任务.

What happens is: all elements from one client are received first, then all elements from other task are received. Why there are not different elements from different task mixed in the channel?

我希望无界通道上的 WriteAsync 始终同步完成。在内部,它只是将项目添加到队列中,并且由于队列总是有空间(在无界通道中),因此没有什么可以使 WriteAsync 异步完成的 AFAIK。因此,您的整个 foreach 循环会同步生成 运行s。

这种行为没有错。如果您的生产者都 运行ning 在不同的线程上,那么他们可能会同时 运行ning 他们的 foreach 循环,并且元素可能会交错。但是每个 foreach 循环都会 运行 非常 ,因此一个线程很可能会在另一个线程有机会之前添加它的所有项目。