Talvez o mais difícil de se trabalhar com múltiplas thread seja a o bloqueio de recursos, onde um recurso não pode ser manipulado por diversas threads simultaneamente ou em determinadas situações que se torna necessário inciar, pausar, retornar e abandonar uma thread manualmente.
O Framework .NET possui o objeto Thread que permite mais flexibilidade e gerenciamento sobre as thread executadas em background do que o objeto ThreadPool.
Thread Priority
Uma das propriedades do objeto Thread á sua prioridade. Após a thread criada, mas antes de iniciar a thread, podemos definir a prioridade da thread com propriedade Thread.Priority usando o enumerador ThreadPriority.
A Thread priority controla como o sistema operacional irá agendar o tempo para a execução da Thread. Geralmente threads com maior prioridade rodam antes das threads com baixo prioridades, por padrão as threads tem o valor de prioridade definida como Normal.
Thread State
Outra propriedade do objeto é Thread.ThreadState pode ser utilizada para verificar o estado das threads em background.
Os estados possíveis são:
- Unstarted: estado inicial da thread (antes de executar o método Thread.Start).
- Running: estado ativo ou executando (após de executar o método Thread.Start).
- Stopped: estado parada.
- WaitSleepJoin: estado esperando outra thread completar.
- SuspendRequested: estado repondendo solicitanção de pausa.
- Suspended: estado suspensa.
- AbortRequested: estado respondendo a solicitanção de abandono.
- Aborted: estado abortado.
Thread com parâmetros e retorno em C#
Para fornecer parâmetros para uma thread, criamos uma classe com um construtor que recebe um ou mais parâmetros e armazena o dado e a usa para criar o objeto ThreadStart.
Para obter o retorno da Thread, criamos um método que recebe o resultado de retorno como uma parâmetro. Depois criamos um delegate para o método e passamos o delegado e próprio método como parâmetro para a classe.
using System; using System.Threading; namespace ManagerThread { public class Program { public static void Main(string[] args) { Calculator calculator = new Calculator("Multiplicador", 15, ResultCallback); Thread thread = new Thread(calculator.Execute); thread.Start(); Console.WriteLine("Main Thread aguarda finalização das threads em background."); thread.Join(); Console.WriteLine("Thread completada."); Console.ReadKey(); } public static void ResultCallback(int value) { Console.WriteLine("Resultado: {0}", value); } } public class Calculator { // Delegate que define a assinatura do método de callback (retorno). public delegate void ResultDelegate(int value); private readonly ResultDelegate callback; private readonly string message; private readonly int value; public Calculator(string message, int value, ResultDelegate callback) { this.message = message; this.value = value; this.callback = callback; } public void Execute() { Console.WriteLine(message); if (callback != null) { callback(value*2); } } } }
A thread é executada somente após o comando thread.Start(). O comando thread.Join() força a thread principal a ficar aguardando a finalização da thread em background para seguir o processo.
Observações:
Threads podem estar em mais de 1 estado ao mesmo tempo.
Os métodos Thread.Suspend e Thread.Resume são utilizados para pausar e retornar a thread principal. Porem estes métos esta depreciados, e podem causar problemas de execuação, utilize o método Thread.Abort().
Enjoy
