A plataforma .NET mantém um pool de threads prontas para serem usadas que são idéias para realizar tarefas rápidas. Geralmente essas threads são usadas para operações assíncronas de acesso a arquivos ou operações realizadas pela chamada de um Delegate ou BeginInvoke.
Delegates são tipos usados para invocar um ou mais métodos onde o método atual invocado é determinado em tempo de execução. Delegates provê uma forma de invocar método pelo seu endereço ao invés de seu nome.
Como estas tarefas são rápidas a criação e destruição das threads passa ter um porção significativa no tempo de execução da tarefa. Para evitar que gerenciamento de linhas de execução (Threads) afete o desempenho, a .NET Framework cria um pool de threads quando necessário até um valor limite e então mantém as threads do pool em estado de espera e prontas para a próxima operação assíncrona. Com isso é ocupada apenas uma pequena quantidade de memória para cada thread otimizando o desempenho.
A classe System.Threading.ThreadPool fornece um número de métodos estáticos que permitem que você monitore e controle as threads do pool.
- GetMinThreads - Retorna o número de threads ociosas que o pool mantém e espera de novas requisições.
- SetMinThreads - Altera o valor mínimo de threads disponíveis no pool. Se você diminuir muito o número de threads ociosas pode afetar o desempenho do sistema;
- QueueUserWorkItem - Enfileira um método para execução. O método será executado quando uma thread do pool estiver disponível. Geralmente você usa este método para executar um processo em outra thread. Pode ser usado da seguinte forma:
QueueUserWorkItem(WaitCallBack) Enfileira um método para execução onde o método executa quando a thread estiver ativa.
QueueUserWorkItem(WaitCallBack, Object) Enfileira um método para execução e especifica um objeto contendo os dados para ser usado pelo método. O método executa quando a thread estiver disponível.
Para exemplificar a utilização destes métodos vamos usar o Visual Basic 2008 Express Edition para criar uma aplicação do tipo Console com o nome de threadPool_1 digitando o código abaixo:
Como já foi mencionado a classe ThreadPool do namespace System.Threading contém um pool virtual de threads disponíveis que você pode usar. Você pode usar a classe ThreadPool para realizar operações assíncronas com recurso de Multithread sem ter que escrever código para gerenciar o pool de threads.
A classe ThreadPool gerencia um grupo dinâmico de threads que estão disponíveis para realizar o processamento multithread. O número de threads no pool é dinâmico e você não é obrigado realizar nenhum trabalho extra para gerenciar as threads no pool. Se você requisitar uma thread e não existir nenhuma disponível, o pool pode criar uma nova thread ou esperar até que uma thread esteja disponível.
O gerenciamento das threads é feita pelo pool de forma transparente e você não tem que se preocupar com esse detalhe apenas com o seu código.
Para demonstrar como usar o recurso ThreadPool e obter o mesmo resultado obtido pela construção de threads vamos propor um problema que simula uma aplicação Windows com um grande processamento inicial. Para forçar uma simulação a aplicação Windows irá carregar 100 milhões de números em um controle ListBox.
Se a aplicação simplesmente tentar carregar os números inteiros no controle ListBox no evento Load do formulário o formulário irá demorar vários minutos para ser exibido mas, se executarmos esta operação em uma thread separada, então o nosso formulário irá exibir o controle ListBox de imediato.
Nota: Observe que podemos usar este recurso pois não precisamos que o processamento de carregar os números na LIstBox esteja concluído para poder exibir a ListBox e aguardar a interação do usuário.
Usando o recurso ThreadPool o formulário será carregado de imediato enquanto a LIstBox continua a ser carregada em segundo plano ficando disponível para a interação com o usuário.
Inclua no formulário padrão form1.vb um controle ListBox e um botão de comando Button conforme o leiaute abaixo:
Estamos usando o método QueueUserWorkItem da classe ThreadPool para enfileirar a execução da rotina carregaLista quando uma thread do pool estiver disponível.( Este método é estático (Shared) e por isso não precisamos criar uma instância da classe ThreadPool)
Esta rotina irá efetivamente carregar o controle ListBox com milhões de números. Observe que o código esta sendo executado no interior de um SyncLock.
A instrução SyncLock garante que múltiplas threads não executem as instruções do bloco ao mesmo tempo e previne que cada thread inicie a execução do código no bloco até que a outra thread terminou de executar o mesmo o código.
Executando o projeto teremos a exibição do formulário com o controle ListBox já preenchido e a rotina para preenchimento continua sendo executada em outra thread.
Observe que usamos a thread a partir do pool através da classe ThreadPool de forma mais simples e sem preocupação em gerenciar threads.
Uma palavra final sobre Threads em aplicações ASP .NET. Com certeza podemos também usar o recurso das threads nas aplicações ASP .NET para por exemplo executar processos que envolvem grandes processamentos no servidor. Como o assunto merece um tratamento a parte irei publicar um artigo a respeito em breve.

Para atender o aumento da oferta de vacina fracionada, uma nova compra de seringas especiais será feita