Você já usou o System.Threading.Channels?
Tags: dotnet, csharp, threads, performance
Published: 2023-09-30 22:56:17

[**System.Threading.Channels**](https://learn.microsoft.com/en-us/dotnet/core/extensions/channels) é uma biblioteca **dotnet** que fornece uma API de canal de comunicação de dados baseada em buffer para sincronização de threads. Essa biblioteca permite que você **transmita dados de forma segura** e **sincronizada** entre threads, tornando mais fácil criar **aplicativos multithread** de **alta performance**.

---

**Antes de continuar, #VemCodar com a gente!!**

Tá afim de criar APIs robustas com .NET?

Feito **de dev para dev**, direto das trincheiras, por quem coloca **software em produção há mais de 20 anos**, o curso ["APIs robustas com ASP.NET Core 8, Entity Framework, Docker e Redis"](https://www.sympla.com.br/evento-online/apis-robustas-com-asp-net-core-8-entity-framework-docker-e-redis/2315443?referrer=www.vemcodar.com.br) traz de maneira direta, sem enrolação, tudo que você precisa saber para construir suas APIs de tal forma que elas sejam seguras, performáticas, escaláveis e, acima de tudo, dentro de um ambiente de desenvolvimento totalmente configurado utilizando Docker e Docker Compose. 

Não fique de fora! Dê um Up na sua carreira!

**O treinamento acontecerá nos dias 27/02, 28/02 e 29/02, online, das 19.30hs às 22.30hs**

**Acesse: [https://vemcodar.com.br/](https://vemcodar.com.br/)**

---

O canal é criado usando uma das implementações fornecidas, como o canal simples ou o canal limitado em tamanho de buffer, e pode ser usado para enviar e receber valores. As operações de envio e recebimento são bloqueadas até que haja espaço disponível no buffer ou até que um valor esteja disponível, respectivamente. Isso garante que as threads sejam sincronizadas e evita o famigerado [**racing condition**](https://www.techtarget.com/searchstorage/definition/race-condition).

Além disso, os canais também fornecem suporte a cancelamentos, o que significa que você pode interromper uma operação de envio ou recebimento em andamento se necessário.
Um exemplo singelo de como usar um canal simples para transmitir dados entre duas threads:

```csharp
using System;
using System.Threading.Channels;
using System.Threading.Tasks;

var channel = Channel.CreateUnbounded<int>(/*Você pode informar uma quantidade máxima de items a serem processados*/);

// Inicia a primeira thread para enviar dados ao canal
var sender = Task.Run(async () =>
{
    for (int i = 0; i < 5; i++)
    {
        Console.WriteLine("Sender enviando: " + i);
        await channel.Writer.WriteAsync(i);
    }
    channel.Writer.Complete();
});

// Inicia a segunda thread para receber dados do canal
var receiver = Task.Run(async () =>
{
    while (await channel.Reader.WaitToReadAsync())
    {
        if (channel.Reader.TryRead(out int item))
        {
            Console.WriteLine("Receiver recebendo: " + item);
        }
    }
});

await Task.WhenAll(sender, receiver);
Console.WriteLine("Todas as mensagens foram transmitidas e recebidas.");
```
No exemplo acima, criamos um canal simples usando **_Channel.CreateUnbounded<int>()_** e iniciamos duas threads. A primeira thread usa o método **_WriteAsync_** do canal para enviar valores inteiros e a segunda thread usa o método **_WaitToReadAsync_** e **_TryRead_** para receber os valores enviados. Quando a primeira thread chama **_channel.Writer.Complete()_**, isso indica que não haverá mais valores a serem transmitidos e a segunda thread para de esperar por novos dados. 

Sem dúvida, o [**System.Threading.Channels**](https://learn.microsoft.com/en-us/dotnet/core/extensions/channels) é uma ferramenta poderosa para sincronização de threads no **dotnet**, que fornece uma API simples e eficiente para garantir que as threads sejam sincronizadas ao transmitir dados. 

Se você estiver trabalhando em um aplicativo multithread, considere usar o [**System.Threading.Channels**](https://learn.microsoft.com/en-us/dotnet/core/extensions/channels) para simplificar a sincronização de threads e melhorar o desempenho do seu aplicativo.

Recomendo esse ótimo post: [An Introduction to System.Threading.Channels — .NET Blog (microsoft.com)](https://devblogs.microsoft.com/dotnet/an-introduction-to-system-threading-channels/)

A documentação é bem completa e recomendo muito a leitura: [Channels — .NET | Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/core/extensions/channels)

Você já usou? Se sim, compartilha conosco o seu caso de uso :)
Até a próxima!