Na era dos processadores multicore a execução concorrente faz cada fez mais sentido, de que serve ter um processador com 8 núcleos se os nossos programas só correm uma tarefa de cada vez, ocupando assim um só núcleo.
Cada vez mais é necessário pensar os programas como pequenas tarefas e quando possível executar essas tarefas concorrentemente, ou seja, em simultâneo, porquê esperar que o disco guarde os dados quando podemos criar um thread que executa a tarefa sem interromper a interface.
A classe THREAD é, na plataforma .NET, o ponto de partida para a execução concorrente.
Com esta classe é possível definir prioridades de execução, pausar e retomar as threads bem como sincronizar diferentes threads entre si, criando relações de execução entre diferentes processos.
Para criar uma nova thread na plataforma .NET o programador precisa de ter uma classe com um método que não possua parâmetros de entrada e que devolva void, ou seja não devolve nada.
É este método que será executado quando a nova thread for iniciada.
Para este post vamos criar uma interface que deverá demonstrar a execução concorrente de três threads, para isso construimos o único form do nosso programa assim:
Os numericupdown vão servir para indicar o tempo de espera de cada thread, assim o valor máximo é 1000, que corresponde a um segundo. Quanto maior este valor mais lento será o enchimento da barra.
As progressbar devem ter um valor máximo de 100, que é o valor por defeito.
A ideia é que cada progressbar vá enchendo de cada vez que o código da thread completa um ciclo de execução.
Agora a classe das threads:
class tarefa
{
private int tempo; //tempo de espera por cada ciclo de execução
public int valor; //valor actual da thread
private int valormax; //valor máximo que interrompe a execução da thread
//construtor
public tarefa(int tempo, int valormax)
{
valor = 1;
this.tempo = tempo;
this.valormax = valormax;
}
//método onde a execução da thread ocorre
public void executa()
{
while (true)
{
Thread.Sleep(tempo);
valor++;
if (valor >= valormax) break; //aqui para o ciclo e a thread "morre"
}
}
}
Um clique no botão Iniciar demo vai executar o seguinte código:
//Esta linha cria um objecto da classe tarefa
t1 = new tarefa((int)this.numericUpDown1.Value,(int)this.progressBar1.Maximum);
//Esta linha cria uma thread associada ao método executa do objecto
thr1 = new Thread(new ThreadStart(t1.executa));
//As restantes linhas criam mais dois objectos
t2 = new tarefa((int)this.numericUpDown2.Value, (int)this.progressBar2.Maximum);
thr2 = new Thread(new ThreadStart(t2.executa));
t3 = new tarefa((int)this.numericUpDown3.Value, (int)this.progressBar3.Maximum);
thr3 = new Thread(new ThreadStart(t3.executa));
//Estas linhas iniciam a execução das três threads
thr1.Start();
thr2.Start();
thr3.Start();
timer1.Enabled = true;
O botão Parar para as três threads:
thr1.Abort();
thr2.Abort();
thr3.Abort();
O botão Pausar/Continuar pausa as threas e remota a sua execução:
if (this.button3.Text == "Pausar")
{
thr1.Suspend();
thr2.Suspend();
thr3.Suspend();
this.button3.Text = "Continuar";
this.button2.Enabled = false;
}
else
{
thr1.Resume();
thr2.Resume();
thr3.Resume();
this.button3.Text = "Pausar";
this.button2.Enabled = true;
}
O método Suspend coloca a execução em suspenso e o método Resume retoma a execução.
Por fim adicionei um timer para actualizar as progressbar refletindo os valores das threads.
O projecto está aqui.
Cada vez mais é necessário pensar os programas como pequenas tarefas e quando possível executar essas tarefas concorrentemente, ou seja, em simultâneo, porquê esperar que o disco guarde os dados quando podemos criar um thread que executa a tarefa sem interromper a interface.
A classe THREAD é, na plataforma .NET, o ponto de partida para a execução concorrente.
Com esta classe é possível definir prioridades de execução, pausar e retomar as threads bem como sincronizar diferentes threads entre si, criando relações de execução entre diferentes processos.
Para criar uma nova thread na plataforma .NET o programador precisa de ter uma classe com um método que não possua parâmetros de entrada e que devolva void, ou seja não devolve nada.
É este método que será executado quando a nova thread for iniciada.
Para este post vamos criar uma interface que deverá demonstrar a execução concorrente de três threads, para isso construimos o único form do nosso programa assim:
Os numericupdown vão servir para indicar o tempo de espera de cada thread, assim o valor máximo é 1000, que corresponde a um segundo. Quanto maior este valor mais lento será o enchimento da barra.
As progressbar devem ter um valor máximo de 100, que é o valor por defeito.
A ideia é que cada progressbar vá enchendo de cada vez que o código da thread completa um ciclo de execução.
Agora a classe das threads:
class tarefa
{
private int tempo; //tempo de espera por cada ciclo de execução
public int valor; //valor actual da thread
private int valormax; //valor máximo que interrompe a execução da thread
//construtor
public tarefa(int tempo, int valormax)
{
valor = 1;
this.tempo = tempo;
this.valormax = valormax;
}
//método onde a execução da thread ocorre
public void executa()
{
while (true)
{
Thread.Sleep(tempo);
valor++;
if (valor >= valormax) break; //aqui para o ciclo e a thread "morre"
}
}
}
Um clique no botão Iniciar demo vai executar o seguinte código:
//Esta linha cria um objecto da classe tarefa
t1 = new tarefa((int)this.numericUpDown1.Value,(int)this.progressBar1.Maximum);
//Esta linha cria uma thread associada ao método executa do objecto
thr1 = new Thread(new ThreadStart(t1.executa));
//As restantes linhas criam mais dois objectos
t2 = new tarefa((int)this.numericUpDown2.Value, (int)this.progressBar2.Maximum);
thr2 = new Thread(new ThreadStart(t2.executa));
t3 = new tarefa((int)this.numericUpDown3.Value, (int)this.progressBar3.Maximum);
thr3 = new Thread(new ThreadStart(t3.executa));
//Estas linhas iniciam a execução das três threads
thr1.Start();
thr2.Start();
thr3.Start();
timer1.Enabled = true;
O botão Parar para as três threads:
thr1.Abort();
thr2.Abort();
thr3.Abort();
O botão Pausar/Continuar pausa as threas e remota a sua execução:
if (this.button3.Text == "Pausar")
{
thr1.Suspend();
thr2.Suspend();
thr3.Suspend();
this.button3.Text = "Continuar";
this.button2.Enabled = false;
}
else
{
thr1.Resume();
thr2.Resume();
thr3.Resume();
this.button3.Text = "Pausar";
this.button2.Enabled = true;
}
O método Suspend coloca a execução em suspenso e o método Resume retoma a execução.
Por fim adicionei um timer para actualizar as progressbar refletindo os valores das threads.
O projecto está aqui.
Comentários
Enviar um comentário