微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

.net 通道:为什么生产者输出在无界通道中被消费者/阅读器一个接一个地连续消耗

如何解决.net 通道:为什么生产者输出在无界通道中被消费者/阅读器一个接一个地连续消耗

主程序启动一个任务,它是 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 是一个高性能的异步就绪生产者/消费者队列。 “高性能”位意味着它会尽可能同步完成。

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

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

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。