How to use channels in c#

Time:2021-7-29

In the faceProducer consumerIn this scenario, NETCORE provides a new namespaceSystem.Threading.ChannelsTo help us deal with such problems more efficiently. With this channel,producerandconsumerThey can handle their own tasks without interfering with each other, which is conducive to the concurrent processing of both parties. In this article, we will discuss how to use themSystem.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, whileSystem.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 do thisproducers and consumers There are generally two benefits of decoupling between:

  • 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, inProducer consumerMode can help us improve the throughput of applications.

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

Essentially, you can create two types of channels, one with limited capacitybound channelOne is infinite capacityunbound channel, the next question is, how to create? Channels offers twoFactory methodUsed to create, as shown in the following code:

  • CreateBoundedThe created channel is a channel with an upper message limit.

  • CreateUnboundedThe created channel is a channel with no upper message limit.

The following code snippet shows how to createunbounded channelAnd can only store string types.

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

by the way,Bounded channelA fullmode attribute is also provided to specify how to process the inserted message when the channel is full. There are usually four methods.

  • Wait

  • DropWrite

  • DropNewest

  • DropOldest

The following code snippet shows how toBounded channelUse fullmode on.

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

Write message to channel

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

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

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

Read messages from channel

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

static async Task Main(string[] args)
        {
            var channel = Channel.CreateBounded(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 the channel.

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

            Console.ReadKey();
        }

        public static async Task SingleProducerSingleConsumer()
        {
            var channel = Channel.CreateUnbounded();
            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);
                }
            }
        }
    }

As you can see, the number is output in the console1-10, these numbers are written into the channel by the writer, right.

In general, if you want to useProducer consumerThere are several ways to implement the scenario, such as blockingcollection and TPL dataflow, but the channels introduced in this article have higher performance than the previous two. I will discuss more details about channels in future articles. If you want to know more quickly now, you can refer to MSDN:https://docs.microsoft.com/en-us/dotnet/api/system.threading.channels?view=netcore-3.0

More exciting, welcome to subscribe

Translation link:https://www.infoworld.com/article/3445156/how-to-use-systemthreadingchannels-in-net-core.html