Take advantage of channels to implement the fast, efficient, asynchronous producer-consumer pattern in .NET Core. Credit: Thinkstock The System.Threading.Channels namespace contains types that you can use to implement a producer-consumer scenario, which speeds up processing by allowing producers and consumers to perform their tasks concurrently. This namespace contains a set of synchronization types that can be used for asynchronous data exchange between producers and consumers. This article discusses how we can work with the System.Threading.Channels library in .NET Core. Dataflow blocks vs. channels The System.Threading.Tasks.Dataflow library encapsulates both storage and processing, and it is focused primarily on pipelining. By contrast, the System.Threading.Tasks.Channels library is focused primarily on storage. Channels are much faster than Dataflow blocks but they are specific to producer-consumer scenarios. That means they don’t support some of the control flow features that you get with Dataflow blocks. Why use System.Threading.Channels? You can take advantage of channels to decouple producers from consumers in a publish-and-subscribe scenario. Producers and consumers not only improve performance by working in parallel, but you can create more producers or consumers should one of those tasks begin to outstrip the other. In other words, the producer-consumer pattern helps to increase the application’s throughput (a measure that denotes the amount of work done in a unit of time). To work with the code examples illustrated in this article, you should have Visual Studio 2019 installed in your system. If you don’t already have a copy, you can download Visual Studio 2019 here. Create a .NET Core Console App project in Visual Studio First off, let’s create a .NET Core project in Visual Studio. Assuming Visual Studio 2019 is installed in your system, follow the steps outlined below to create a new .NET Core Console App. Launch the Visual Studio IDE. Click on “Create new project.” In the “Create new project” window, select “Console App (.NET Core)” from the list of the templates displayed. Click Next In the “Configure your new project” window shown next, specify the name and location for the new project. Click Create. This will create a new .NET Core Console App project in Visual Studio 2019. We’ll use this project to illustrate the use of System.Threading.Channels in the subsequent sections of this article. Install theSystem.Threading.Channels NuGet package Now that we have created a .NET Core Console App in Visual Studio, the next thing you should do is install the necessary NuGet package. The package you need to install is System.Threading.Channels. You can install this package from the NuGet Package Manager inside the Visual Studio 2019 IDE. Alternatively, you can enter the following command to install this package via the .NET CLI. dotnet add package System.Threading.Channels Create a channel in .NET Core Essentially, you can have two different types of channels. These include a bounded channel with a finite capacity and an unbounded channel with unlimited capacity. You can create either type of channel using the Channel static class that is available as part of the System.Threading.Channels namespace. The Channel class provides the following two factory methods that can be used to create the two kinds of channels. CreateBounded is used to create a channel that holds a finite number of messages. CreateUnbounded is used to create a channel with unlimited capacity, i.e., a channel that (theoretically) holds an infinite number of messages. The following code snippet illustrates how an unbounded channel can be created. Note that this channel can hold string objects only. var channel = Channel.CreateUnbounded<string>(); Bounded channel options include a FullMode property that is used to denote the behavior of the channel during a write operation when the channel is full. Bounded channels can make use of any of the following FullMode behaviors: Wait DropWrite DropNewest DropOldest The following code snippet illustrates how you can create a bounded channel and set the FullMode property. Channel.CreateBounded<string>(new BoundedChannelOptions(1000) { FullMode = BoundedChannelFullMode.Wait }); Write data to a channel in .NET Core To write data to a channel, you can use the WriteAsync method as shown in the code snippet given below. await channel.Writer.WriteAsync("Hello World!"); Read data from a channel in .NET Core To read data from a channel you can leverage the ReadAsync method as shown in the code snippet given below. while (await reader.WaitToReadAsync()) { if (reader.TryRead(out var message)) { Console.WriteLine(message); } } System.Threading.Channels example Here is the complete code listing that demonstrates writing and reading data to and from a 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); } } } } When executed, the above program will display the numbers 1 to 10 sequentially at the console window. There are several ways of implementing a producer-consumer pattern, such as by using BlockingCollection or TPL Dataflow. However, channels are much faster and more efficient than either of these. I’ll discuss channels in further detail in future posts. Until then, you can learn more about the System.Threading.Channels namespace from Microsoft’s online documentation. Related content news Wasmer WebAssembly platform now backs iOS Wasmer 5.0 release also features improved performance, a leaner codebase, and discontinued support for the Emscripten toolchain. By Paul Krill Oct 30, 2024 2 mins Mobile Development Web Development Software Development news analysis What Entrust certificate distrust means for developers Secure communications between web browsers and web servers depend on digital certificates backed by certificate authorities. What if the web browsers stop trusting your CA? By Travis Van Oct 30, 2024 9 mins Browser Security Web Development Application Security news Next.js 15 arrives with faster bundler High-performance Rust-based Turbopack bundler moves from beta to stable with the latest update of the React-based web framework. By Paul Krill Oct 24, 2024 2 mins JavaScript React Web Development feature WasmGC and the future of front-end Java development WebAssembly’s garbage collection extension makes it easier to run languages like Java on the front end. Could it be the start of a new era in web development? By Matthew Tyson Oct 16, 2024 10 mins Web Development Software Development Resources Videos