sexta-feira, 22 de julho de 2011

Threads em CSharp (C#)

Pessoal hoje vamos falar sobre threads na linguagem CSharp (C#). Threads possuem várias finalidades, mas a que aqui, hoje trabalharemos, será manter uma interface que continue interagindo com o usuário, mesmo que algum processamento pesado esteja acontecendo.

Vamos ao nosso exemplo prático: Vamos criar uma função que calcula números primos e vamos mostrar o resultado em uma caixa de texto. Nossa interface será como a que segue:


Caixa de Texto, propriedades que alteramos:
Name: textBoxResult
Multiline: true
Scrolls Bars: Both

Botões:
Calc:
Name: buttonCalc
Text: Calc


CalcThread:
Name: buttonThread
Text: CalcThread

OutraTarefa:
Name: buttonOutraTarefa
Text: OutraTarefa

Nosso código

Namespaces que vamos utilizar:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;


Todos esses são default do VisualStudio, exceto um: System.Threading, ele conterá tudo que precisaremos para trabalhar com a Thread de nosso exemplo.

Código do botão Calc:

private void buttonCalc_Click(object sender, EventArgs e)
{
int maxNum = 10000;
int contador = 2;
int resto=1;
while (contador <= maxNum)
{
for (int x = 2; x < contador; x++)
{
resto = contador % x;
if ( resto == 0)
{
break;
}
}
if (resto != 0)
textBoxResult.Text = textBoxResult.Text + " " + contador.ToString();
contador++;
}

}

Código do botão CalcThread:

prime = new Thread(calculaPrimos);
prime.Start();

Bom vamos ver nossas funções auxiliares, primeiramente vamos verificar a função calculaPrimos:

public void calculaPrimos()
{
int maxNum = 10000;
int contador = 2;
int resto=1;
while (contador <= maxNum)
{
for (int x = 2; x < contador; x++)
{
resto = contador % x;
if ( resto == 0)
{
break;
}
}

if (resto != 0)
textBoxResult.Invoke(new escreveTxtDelegate(escreveTxt), new object[] { contador});
contador++;
}

}


Para escrevermos em controles que não foram criados dentro de nossa thread, precisamos fazer o uso de delegates e usamos o método invoke do textBoxResul.
Bom o delegate pode estar declarado no início, como um membro da classe, assim como nossa thread:

public delegate void escreveTxtDelegate(int contador);
Thread prime;

Nossa função para escrever no TextBox, usada pelo Delegate:

public void escreveTxt(int contador)
{
textBoxResult.Text = textBoxResult.Text + " " + contador.ToString();
}

Bom agora para finalizarmos o código de nosso botão OutraTarefa:

private void buttonOutraTarefa_Click(object sender, EventArgs e)
{
MessageBox.Show("Executando outra tarefa", "NumPrimos");
}
Para testarmos nossa aplicação, vamos fazer da seguinte maneira:

Vamos executar o programa e pressionar o botão “Calc”, se você tentar pressionar o botão OutraTarefa ele não vai mostrar a mensagem “Executando outra Tarefa”. E também se você tentar mexer a tela do programa a mesma não vai responder. Agora vamos fazer outro teste, ao invés de clicarmos no botão “Calc”, vamos clicar no botão “CalcThread” assim você poderá perceber que a mensagem será mostrada e também poderá movimentar a tela do aplicativo enquanto o processamento matemático está ocorrendo.








Nenhum comentário:

Postar um comentário