How to use channels in C # 8

Time:2021-7-23

In the faceProducer consumerIn this scenario, NETCORE provides a new namespaceSystem.Threading.ChannelsTo help us deal with such problems more efficiently. With the existence of this channel,producerandconsumerCan handle their own tasks without interfering with each other, is conducive to the concurrent processing of both sides, this article we will discuss how to useSystem.Threading.Channels

Dataflow vs Channel

staySystem.Threading.Tasks.DataflowA data flow library is provided under the namespace, which mainly encapsulatesstorageandhandleThe library focuses on pipeline processing, while theSystem.Threading.Tasks.ChannelsMainly focus onstorageThis, in terms of single responsibility, isProducer consumerIn this scenario, the performance of channels is much higher than that of dataflow.

Why use channels

You can use channels to achieve thisproducers and consumers In general, there are two advantages to the decoupling between them

  • Producers and consumers are independent of each other, and they can be executed in parallel.
  • If the producers do not suck up, they can create more producers. If consumers do not suck up, they can create more consumers.

In general, in theProducer consumerMode can help us improve the throughput of the application.

Install system.threading.channels

To use channel, you need to use nuget referenceSystem.Threading.ChannelsPackage, you can also use theNuGet package managerVisual interface installation or throughNuGet package managerThe command line tool enters the following command:


dotnet add package System.Threading.Channels

Create channel

In essence, you can create two types of channels, one with limited capacitybound channelOne is infinite capacityunbound channelThe next question is, how to create it? Channels offers two optionsFactory approachUsed to create, as shown in the following code:

  • CreateBounded<T>The created channel is a channel with an upper limit of messages.
  • CreateUnbounded<T>The created channel is a channel with no upper message limit.

The following code snippet shows how to createunbounded channel, and can only store string types.


        static void Main(string[] args)
        {
            var channel = Channel.CreateUnbounded<string>();
        }

by the way,Bounded channelIt also provides a fullmode attribute to specify how to handle the inserted message when the channel is full. There are four ways to do this.

  • Wait
  • DropWrite
  • DropNewest
  • DropOldest

The following code snippet shows how toBounded channelUse fullmode on.


        static void Main(string[] args)
        {
            var channel = Channel.CreateBounded<string>(new BoundedChannelOptions(1000)
            {
                FullMode = BoundedChannelFullMode.Wait
            });
        }

Write message to channel

To write a message to a channel, you can use theWriteAsync()Method, as shown in the following code:


        static async Task Main(string[] args)
        {
            var channel = Channel.CreateBounded<string>(new BoundedChannelOptions(1000)
            {
                FullMode = BoundedChannelFullMode.Wait
            });

            await channel.Writer.WriteAsync("Hello World!");
        }

Read message from channel

To read messages from channel, you can use theReadAsync(), as shown in the following code:


        static async Task Main(string[] args)
        {
            var channel = Channel.CreateBounded<string>(new BoundedChannelOptions(1000)
            {
                FullMode = BoundedChannelFullMode.Wait
            });

            while (await channel.Reader.WaitToReadAsync())
            {
                if (channel.Reader.TryRead(out var message))
                {
                    Console.WriteLine(message);
                }
            }
        }

System. Threading. Channels example

The following is a complete code listing showing how to read and write messages from channel.


    class Program
    {
        static async Task Main(string[] args)
        {
            await SingleProducerSingleConsumer();

            Console.ReadKey();
        }

        public static async Task SingleProducerSingleConsumer()
        {
            var channel = Channel.CreateUnbounded<int>();
            var reader = channel.Reader;
            for (int i = 0; i < 10; i++)
            {
                await channel.Writer.WriteAsync(i + 1);
            }

            while (await reader.WaitToReadAsync())
            {
                if (reader.TryRead(out var number))
                {
                    Console.WriteLine(number);
                }
            }
        }
    }

How to use channels in C # 8

As you can see, the number is output in the console1-10These numbers are exactly what the writer writes to the channel, right.

In general, if you want to useProducer consumerThere are several ways to realize the scenario, such as blockingcollection and TPL dataflow. However, the performance of channels introduced in this article is higher than that of the previous two. I will discuss more details about channels in future articles. If you want to know more about them now, you can refer to MSDN: https://docs.microsoft.com/en…

Translation link: https://www.infoworld.com/art…

More high quality dry goods: see my GitHub: csharptranslate