Multithreading em C#: benefícios, princípios básicos e práticas recomendadas

Publicados: 2023-06-01

Índice

O que é programação multi-thread

Multithreading é um conceito fundamental na engenharia de software. Em C#, a programação multithread é essencial para desenvolvedores de software que trabalham com o .NET Framework. Os desenvolvedores usam amplamente o multithreading em C# , pois permite criar aplicativos complexos e responsivos com eficiência.

Este blog fornece uma visão geral do multithreading c# enquanto, ao mesmo tempo, também analisa como os programadores podem criar e gerenciar threads facilmente. Ele também inclui os benefícios de usar multithreading e os diferentes modelos de threading disponíveis em C#.

Benefícios e vantagens da programação multithread

Quando executado simultaneamente, o multithreading melhora a eficácia dos aplicativos. Os benefícios mais comuns do thread C# incluem o seguinte:

  • Desempenho aprimorado do aplicativo: com a ajuda do multithreading, os aplicativos são executados mais rapidamente com várias tarefas executadas no mesmo espaço.Em sua totalidade, reduz o tempo de execução e dá lugar a múltiplas tarefas.
  • Taxa de transferência aumentada: a multitarefa em C# aumenta a taxa de transferência de aplicativos.Quando dois threads diferentes são executados simultaneamente, isso pode economizar tempo e recursos.
  • Capacidade de resposta aprimorada: com a ajuda de multithreading, um usuário pode acessar o front-end do aplicativo enquanto o programa é executado em segundo plano.
  • Maior utilização de recursos: o multithreading permite que os usuários acessem os recursos do sistema com mais eficiência.Por exemplo, threads podem compartilhar recursos como arquivos, memória e dispositivos de E/S, abrindo caminho para a eficiência.
  • Programação mais acessível: o multithreading permite uma programação mais fácil, pois os usuários podem escrever threads independentemente.Ele também permite que os usuários depurem e testem aplicativos isoladamente.
  • Comunicação otimizada: a sincronização de threads permite uma melhor comunicação entre processos.Ele pode ser usado para uma comunicação mais acessível entre threads.

Em primeiro lugar, afeta objetos individuais que podem ser sincronizados. Em segundo lugar, pode ser usado com as classes System.Threading e Interlocked.

Conceitos Básicos de Multithreading em C#

O multithreading permite que os usuários executem várias tarefas simultaneamente com a ajuda de vários núcleos de processador. Aqui estão os conceitos básicos usados ​​em multithreading:

  • Threads: Threads são as unidades básicas em multithreading que ajudam a executar um processo.Esses são caminhos de execução dentro de um determinado programa que podem ser executados simultaneamente com outros threads.

Em C#, podemos encontrar dois tipos de threads, a saber, threads de primeiro plano e de segundo plano. A classe de thread média inclui um nome, prioridade, isAlive, ThreadState, Start(), Suspend(), Resume() e Join().

  • Pool de threads: Um pool de threads é um thread que ajuda a executar tarefas.Ele permite que o sistema operacional reutilize threads existentes e minimize o risco de possíveis sobrecargas.
  • Sincronização: A sincronização está negligenciando o acesso a outros threads para várias operações.É um processo essencial para manter a integridade dos dados e evitar sobrecargas.
  • Deadlock: Um deadlock é um erro que ocorre quando duas threads compartilham recursos e tentam prosseguir sem sucesso.Isso pode fazer com que o sistema congele ou até mesmo levar a um tempo de espera.
  • Programação assíncrona: a programação assíncrona permite a execução de várias tarefas em segundo plano, permitindo que o thread principal seja executado sem interrupção.Ele abre caminho para várias interfaces de usuário responsivas, aprimorando o desempenho do aplicativo.

Criando e Executando Tópicos

Criar e executar pode ser mais fácil com esses exemplos. Um exemplo de multithreading em C# é fornecido abaixo:

usando Sistema;

usando System.Threading;

programa de classe {

static void Main() {

int workIndex = 0;

Thread workerThread = new Thread(new ThreadStart(Worker));

workerThread.Start();

for (int mainIndex = 1; mainIndex <= 10; mainIndex++) {

Console.WriteLine(“Encadeamento principal: {0}”, mainIndex);

Thread.Sleep(200);

}

workerThread.Join();

}

static void Worker() {

for (int workerIndex = 1; workerIndex <= 10; workerIndex++) {

Console.WriteLine(“Thread de trabalho: {0}”, workerIndex * 2);

Thread.Sleep(200);

}

}

}

Saída:

Tópico principal: 1

Linha de trabalho: 2

Linha principal: 2

Linha de trabalho: 4

Linha principal: 3

Linha de trabalho: 6

Linha principal: 4

Fio de trabalho: 8

Linha principal: 5

Linha de trabalho: 10

Fio principal: 6

Linha de trabalho: 12

Linha principal: 7

Fio de trabalho: 14

Fio principal: 8

Fio de trabalho: 16

Linha principal: 9

Fio de trabalho: 18

Fio principal: 10

Linha de trabalho: 20

Explicação: Nesta saída, ambos os encadeamentos trabalham simultaneamente para imprimir os números 1 a 10 e 2 a 20, o último dobrado do índice de loop.Neste exemplo, o método C# thread sleep (Thread.Sleep) foi usado.

Da mesma forma, veremos outro exemplo de thread C# usando o thread de primeiro plano:

usando Sistema;

usando System.Threading;

programa de classe {

static void Main() {

Thread myThread = new Thread(Worker);

myThread.Start();

Console.WriteLine(“Thread Principal: Iniciado”);

for (int i = 1; i <= 5; i++) {

Console.WriteLine(“Thread Principal: Contagem {0}”, i);

Thread.Sleep(500);

}

Console.WriteLine("Tópico Principal: Encerrado");

}

static void Worker() {

for (em j = 1; j <= 5; j++) {

Console.WriteLine(“Thread de Trabalho: Contagem {0}”, j * 3);

Thread.Sleep(750);

}

Console.WriteLine(“Thread de Trabalho: Encerrado”);

}

}

Saída:

Tópico Principal: Iniciado

Tópico de trabalho: Contagem 3

Tópico Principal: Contagem 1

Tópico de trabalho: Contagem 6

Tópico Principal: Contagem 2

Tópico de trabalho: Contagem 9

Tópico Principal: Contagem 3

Tópico de trabalho: Contagem 12

Tópico Principal: Contagem 4

Tópico de trabalho: Contagem 15

Tópico Principal: Contagem 5

Tópico de trabalho: encerrado

Tópico principal: encerrado

Explicação: Esta saída mostra como os dois encadeamentos funcionam simultaneamente.Como os threads principal e de segundo plano trabalham em paralelo, o thread principal imprime números de 1 a 5. O thread de trabalho imprime múltiplos de 3 a 15.

Confira os cursos de desenvolvimento de software na upGrad para aprimorar suas habilidades.

Leia nossos artigos populares relacionados ao desenvolvimento de software

Por que aprender a codificar? Como aprender a codificar? Como instalar a versão específica do pacote NPM? Tipos de herança em C++ O que você deve saber?

Sincronização de Threads

A sincronização de threads envolve a coordenação coletiva de vários threads em um programa. Ele garante que o programa seja executado em uma ordem específica, dando acesso a recursos compartilhados.

Em C#, isso é feito usando primitivas de sincronização como a palavra-chave lock, objetos de sincronização e a classe Interlocked.

Um exemplo de sincronização de thread C# é dado abaixo:

Usando Sistema;

Usando System.Threading;

classe TablePrinter

{

public void PrintTable()

{

trancar (este)

{

for (int i = 3; i <= 8; i++)

{

Thread.Sleep(200);

Console.WriteLine(i*5);

}

}

}

}

programa de classe

{

public static void Main(string[] args)

{

TablePrinter tp = new TablePrinter();

Thread t1 = new Thread(new ThreadStart(tp.PrintTable));

Thread t2 = new Thread(new ThreadStart(tp.PrintTable));

t1.Start();

t2.Start();

}

}

Saída:

15

20

25

30

35

40

45

50

55

60

Explore nossos cursos gratuitos de desenvolvimento de software

Fundamentos da Computação em Nuvem Noções básicas de JavaScript do zero Estruturas de Dados e Algoritmos
Tecnologia Blockchain Reagir para iniciantes Noções básicas de Java
Java Node.js para Iniciantes JavaScript Avançado

Impasses

Deadlocks em multithreading acontecem quando pelo menos dois ou mais threads dependem de um conjunto de recursos. Quando um thread sobrepõe a rota para a ajuda enquanto o outro tenta fazer o mesmo, torna-se um impasse.

Por exemplo, se o Thread A tiver um bloqueio no Recurso 1 e estiver esperando para acessar o Recurso 2 enquanto o Thread B aguarda o Recurso 1, isso pode resultar em um impasse.

Um exemplo é dado abaixo:

usando Sistema;

usando System.Threading;

namespace deadlockincsharp

{

exemplo de classe pública

{

objeto somente leitura estático firstLock = new object();

objeto somente leitura estático secondLock = new object();

estático void ThreadJob()

{

Console.WriteLine(“\t\t\t\tLocking firstLock”);

lock (firstLock)

{

Console.WriteLine(“\t\t\t\tLocked firstLock”);

Thread.Sleep(1500);

Console.WriteLine(“\t\t\t\tLocking secondLock”);

lock (secondLock)

{

Console.WriteLine(“\t\t\t\tLocked secondLock”);

}

Console.WriteLine(“\t\t\t\tReleased secondLock”);

}

Console.WriteLine(“\t\t\t\tReleased firstLock”);

}

static void Main()

{

novo Thread(new ThreadStart(ThreadJob)).Start();

Thread.Sleep(1000);

Console.WriteLine("Bloqueando segundoLock");

lock (secondLock)

{

Console.WriteLine("Segunda trava bloqueada");

Console.WriteLine(“Bloqueando firstLock”);

lock (firstLock)

{

Console.WriteLine(“Locked firstLock”);

}

Console.WriteLine(“Liberado firstLock”);

}

Console.WriteLine(“Liberado secondLock”);

Console.Read();

}

}

}

Saída:

Bloqueio segundoLock

Bloqueado segundo Bloqueio

Bloqueando primeiro Bloquear

Bloqueado primeiro Bloquear

Lançado primeiroLock

SecondLock liberado

Habilidades de desenvolvimento de software sob demanda

Cursos de JavaScript Cursos Básicos de Java Cursos de estruturas de dados
Cursos de Node.js Cursos de SQL Cursos de desenvolvimento full stack
Cursos NFT Cursos DevOps Cursos de Big Data
Cursos React.js Cursos de segurança cibernética Cursos de computação em nuvem
Cursos de Design de Banco de Dados Cursos de Python Cursos de Criptomoedas

Conjuntos de threads

Os pools de threads ajudam a gerenciar vários threads de execução em um ambiente multithread em C#. Isso garante que todas as threads tenham acesso aos recursos controlados sem causar deadlocks.

Um gerenciador de pool de threads cuida do pool de threads, onde é responsável por criar, destruir e agendar threads.

Aqui está um exemplo de pool de threads usando TPL (Task Parallel Library):

usando Sistema;

usando System.Threading.Tasks;

programa de classe

{

static void Main()

{

Tarefa<string> tarefa = Task.Factory.StartNew<string>

(() => DownloadString(“http://www.example.com/”));

string resultado = tarefa.Resultado;

Console.WriteLine(resultado);

Console.Read();

}

string estática DownloadString(string uri)

{

usando (var wc = new System.Net.WebClient())

return wc.DownloadString(uri);

}

Saída:

A saída depende dos conteúdos disponíveis na página web. Este programa garantirá o download do conteúdo da página da Web a partir do URL especificado. Em seguida, ele os imprimirá.

Programação assíncrona com biblioteca paralela de tarefas (TPL)

A Task Parallel Library (TPL) é uma ferramenta poderosa para lidar com APIS e tipos públicos. Ele lida com System.Threading e System.Threading.Tasks .

O .NET Framework 4 oferece APIs de nível de linguagem e estrutura para desenvolvedores que desejam escrever código paralelo. Com a ajuda do TPL, a programação assíncrona permite que os programas sejam executados sem bloquear o thread principal.

Aqui está um exemplo de programação assíncrona com TPL:

Tarefa<string> tarefa = Task.Factory.StartNew<string>(() => {

retorna “resultado”;

});

string resultado = tarefa.Resultado;

Tarefa assíncrona MeuMétodo() {

string resultado = aguarda tarefa;

}

Confira nossoscursos de tecnologia gratuitos para obter uma vantagem sobre a concorrência.

Práticas recomendadas para multithreading em C#

O multithreading pode economizar tempo em termos de desempenho e multitarefa. Para saber mais sobre como funciona o multithreading, você pode optar por um Mestrado em Ciência da Computação da LJMU .

Aqui estão algumas práticas recomendadas para ajudar os usuários a economizar tempo e registrar a mais alta eficiência.

  • Utilize coleções thread-safe: as coleções simultâneas do .NET Framework fornecem uma versão thread-safe de cada coleção, o que facilita o trabalho eficiente de multithreading.Essas coleções incluem listas e consultas e dicionários.
  • Implementar sincronização de threads: os usuários podem implementar bloqueios, monitores e semáforos rapidamente devido à natureza das ferramentas de threads.
  • Use o pool de threads: o multithreading pode ser mais fácil e eficiente para os sistemas, graças à grande maioria do pool de threads feito pelos usuários.Ao mesmo tempo, os usuários podem usá-lo para criar tópicos automaticamente.
  • Use armazenamento local de thread: ao praticar multithreading, garanta o acesso a um recurso específico otimizando o armazenamento local de thread e oferecendo acesso a vários threads.
  • Evite compartilhar estados mutáveis: estados mutáveis ​​compartilhados só levarão a bugs e condições de corrida, o que pode ser complicado.Certifique-se de evitar estados mutáveis ​​a qualquer custo.
  • Usar modelo assíncrono: os métodos assíncronos ajudam a implementar várias tarefas em paralelo sem iniciá-las novamente ou deixá-las na fila.
  • Evite deadlocks: Deadlocks podem ser esperados ao executar programas usando multithreading.Ao escrever um programa, tente executar uma thread somente após a outra, evitando deadlocks.
  • Use tokens de cancelamento: os tokens de cancelamento permitem que os encadeamentos sejam encerrados sem problemas e evitam deadlocks.

Explore nossos cursos populares de engenharia de software

Mestre em Ciência da Computação pela LJMU & IIITB Programa de Certificação de Cibersegurança Caltech CTME
Bootcamp de Desenvolvimento Full Stack Programa PG em Blockchain
Programa Executivo PG em Desenvolvimento Full Stack
Veja todos os nossos cursos abaixo
Cursos de Engenharia de Software

Conclusão

Multithreading em C# continua sendo um conceito essencial com seu modelo de alta eficiência em funcionamento. Ele fornece uma maneira flexível para os programadores dividirem a carga de trabalho de um programa em várias tarefas executadas simultaneamente e de forma independente.

Embora o multithreading possa ser altamente benéfico, ele pode levar a possíveis obstáculos se não for implementado com cuidado.

Com o orçamento global para software empresarial excedendo US$ 856 bilhões entre 2009-2023, o desenvolvimento de software promete uma carreira brilhante para os desenvolvedores.

Inscreva-se no Full Stack Software Development Bootcamp da upGrad agora! Um curso de desenvolvimento full stack pode ser o trampolim para desenvolvedores que desejam liberar seu potencial em ciência da computação.

1. O que é programação multithread?

A programação multithread é um processo que envolve a execução de programas usando vários threads simultaneamente. Ele permite que os usuários no front-end usem várias cópias do programa em execução no computador sem interrupção.

2. Qual é a principal diferença entre thread e processo?

Um processo normalmente envolve um programa em estado de execução, enquanto um thread consiste em um processo dentro de um subprocesso.

3. Qual é a diferença entre um thread e uma tarefa em C#?

Um thread em C# lida com a construção e gerenciamento de um pool de threads destinado à programação. Por outro lado, uma tarefa representa uma função assíncrona operando em segundo plano.