AdtG
AdtG

Reputation: 27

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

Main program starts a task which is consumer task for Channel. Consumer task code is :

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

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

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

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?

Upvotes: 0

Views: 418

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456577

Channels is a high-performance async-ready producer/consumer queue. The "high performance" bit means it will complete synchronously whenever possible.

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

This is fine. The first thing I'd check is whether each client is running on a separate thread (e.g., Task.Run), or if they're just async tasks.

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?

I would expect a WriteAsync on an unbounded channel to always complete synchronously. Internally, it's just adding the item to a queue, and since the queue always has room (in an unbounded channel), there's nothing AFAIK that would make WriteAsync complete asynchronously. So the entire foreach loop in your produces runs synchronously.

There's nothing wrong with this behavior. If your producers are all running on different threads, then they may be running their foreach loops concurrently, and the elements may be interleaved. But each foreach loop will run very quickly, so it's likely that one thread will add all its items before another thread gets a chance.

Upvotes: 3

Related Questions