Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O .NET fornece vários tipos que são úteis na programação paralela, incluindo um conjunto de classes de coleção simultâneas, primitivos de sincronização leve e tipos para inicialização lenta. Você pode usar esses tipos com qualquer código de aplicativo multiencadeado, incluindo a Biblioteca Paralela de Tarefas e PLINQ.
Classes de coleção simultâneas
As classes de coleção no namespace System.Collections.Concurrent fornecem operações de adição e remoção thread-safe que, sempre que possível, evitam bloqueios e usam o bloqueio refinado quando os bloqueios forem necessários. Uma classe de coleção simultânea não exige que o código de usuário faça bloqueios ao acessar itens. As classes de coleção simultâneas podem melhorar significativamente o desempenho em relação a tipos como System.Collections.ArrayList e System.Collections.Generic.List<T> (com bloqueio implementado pelo usuário) em cenários em que vários threads adicionam e removem itens de uma coleção.
A tabela a seguir lista as classes de coleção simultâneas:
| Tipo | Descrição |
|---|---|
| System.Collections.Concurrent.BlockingCollection<T> | Fornece funcionalidades de bloqueio e delimitação para coleções thread-safe que implementam System.Collections.Concurrent.IProducerConsumerCollection<T>. Os threads de produtor são bloqueados se nenhum slot estiver disponível, ou se a coleção estiver cheia. Threads de consumidor são bloqueados se a coleção estiver vazia. Esse tipo também dá suporte ao acesso não bloqueado por consumidores e produtores. BlockingCollection<T> pode ser usado como uma classe base ou repositório de backup para fornecer bloqueio e limitação a qualquer classe de coleção que ofereça suporte a IEnumerable<T>. |
| System.Collections.Concurrent.ConcurrentBag<T> | Uma implementação de recipiente thread-safe que fornece operações de adição e get escalonáveis. |
| System.Collections.Concurrent.ConcurrentDictionary<TKey,TValue> | Um tipo de dicionário simultâneo e escalonável. |
| System.Collections.Concurrent.ConcurrentQueue<T> | Uma fila FIFO simultânea e escalonável. |
| System.Collections.Concurrent.ConcurrentStack<T> | Uma pilha LIFO simultânea e escalonável. |
Para obter mais informações, consulte Thread-Safe Collections.
Primitivos de sincronização
Os primitivos de sincronização no System.Threading namespace permitem simultaneidade refinada e um desempenho mais rápido, evitando mecanismos de bloqueio caros encontrados no código de multithreading herdado.
A tabela a seguir lista os tipos de sincronização:
| Tipo | Descrição |
|---|---|
| System.Threading.Barrier | Permite que vários threads funcionem em um algoritmo em paralelo fornecendo um ponto em que cada tarefa pode sinalizar sua chegada e, depois, gerar um bloqueio até que algumas ou todas as tarefas tenham chegado. Para obter mais informações, consulte Barreira. |
| System.Threading.CountdownEvent | Simplifica cenários de bifurcação e junção fornecendo um mecanismo fácil de encontro. Para obter mais informações, consulte CountdownEvent. |
| System.Threading.ManualResetEventSlim | Um primitivo de sincronização semelhante a System.Threading.ManualResetEvent. ManualResetEventSlim é mais leve, mas só pode ser usado para comunicação intraprocesso. |
| System.Threading.SemaphoreSlim | Um primitivo de sincronização que limita o número de threads que podem acessar simultaneamente um recurso ou um pool de recursos. Para obter mais informações, consulte Semaphore e SemaphoreSlim. |
| System.Threading.SpinLock | Um primitivo de bloqueio de exclusão mútua que faz com que o thread que está tentando adquirir o bloqueio aguarde em um loop, ou rotação, durante um período antes de gerar seu quantum. Em cenários em que a espera pelo bloqueio deve ser curta, SpinLock oferece melhor desempenho do que outras formas de bloqueio. Para obter mais informações, consulte SpinLock. |
| System.Threading.SpinWait | Um tipo de pequeno e leve que girará por um tempo especificado e, no final, colocará o thread em um estado de espera se a contagem de rotações for ultrapassada. Para obter mais informações, consulte SpinWait. |
Para obter mais informações, consulte:
Classes de inicialização lentas
Com a inicialização lenta, a memória de um objeto não é alocada até que seja necessária. A inicialização lenta pode melhorar o desempenho espalhando alocações de objeto uniformemente durante o tempo de vida de um programa. Você pode habilitar a inicialização lenta para qualquer tipo personalizado encapsulando o tipo Lazy<T>.
A tabela a seguir lista os tipos de inicialização lentos:
| Tipo | Descrição |
|---|---|
| System.Lazy<T> | Fornece inicialização lenta, leve e thread-safe. |
| System.Threading.ThreadLocal<T> | Fornece um valor com inicialização lenta em uma base por thread, com cada thread invocando lentamente a função de inicialização. |
| System.Threading.LazyInitializer | Fornece métodos estáticos que evitam a necessidade de alocar uma instância dedicada e lenta de inicialização. Em vez disso, usam referências para garantir que os destinos sejam inicializados conforme são acessados. |
Para obter mais informações, consulte Inicialização Lenta.
Exceções agregadas
O System.AggregateException tipo pode ser usado para capturar várias exceções que são lançadas simultaneamente em threads separados e devolvê-las ao thread de junção como uma única exceção. Para essa finalidade, os tipos System.Threading.Tasks.Task, System.Threading.Tasks.Parallel e PLINQ usam AggregateException extensivamente. Para obter mais informações, consulte Tratamento de Exceções e Como lidar com exceções em uma consulta PLINQ.