Na primeira parte deste artigo apresentei os conceitos básicos do gerenciamento de processos e de como usar threads em formulários Windows Forms de maneira segura. Continuando vamos mostrar como aplicar esses conceitos em uma aplicação Windows Forms. |
Recursos usados
Objetivos
Aprendizado
Criando o projeto no Visual Studio 2013
1- Mostrando o efeito de usar Threads de forma insegura
Abra o Visual Studio 2013 Express for Windows Desktop e clique em New Project;
Selecione o template Visual C# -> Windows -> Windows Forms Application e informe o nome Usando_Threads e clique em OK;
No formulário form1.cs inclua os seguintes controles:
Disponha os controles conforme o leiaute abaixo:
No início do formulário form1.cs declare o namespace para utilizar threads:
using System.Threading;
A seguir no evento Click do botão de comando inclua o código abaixo:
private void btnThreadNaoSegura_Click(object sender, EventArgs e)
{
Thread th = new Thread(new ThreadStart(this.Thread_Nao_Segura));
th.Start();
txtTexto.Text = "Texto inserido pela Thread Principal.";
}
|
A seguir temos o código da rotina Thread_Nao_Segura que será chamada pela thread em segundo plano no formulário form1.cs:
private void Thread_Nao_Segura()
{
Thread.Sleep(2000);
this.txtTexto.Text = "Texto Escrito de forma não segura pela Thread em segundo plano.";
}
|
O exemplo é bem simples e para um programador ingênuo aparentemente ele não apresenta erros, até ser executado...
Ao executar o programa e clicar no botão de comando o resultado abaixo será apresentado:
Seguindo a sequência de execução das linhas de código será criada uma instância de uma nova Thread e seu método Start() será acionado.
A seguir o texto "Texto inserido pela Thread Principal." será inserido na caixa de texto e apresentado ao usuário.
Mas após dois segundos a rotina Thread_Nao_Segura será executada tentando inserir o texto - Texto Escrito de forma não segura pela Thread - em segundo plano - na caixa de texto. Veja que isso esta ocorrendo em outra thread diferente da thread principal.
O resultado obtido será uma exceção:
Veja a mensagem : Operação entre threads inválida: controle 'txtTexto' acessado de um thread que não é aquele no qual foi criado.
Creio que não preciso dizer mais nada...
2- Mostrando a solução padrão de como usar Threads de forma segura
Usando o projeto criado anteriormente, acesse o menu PROJECT e clique em Add Windows Forms e aceite o nome padrão form2.cs.
A seguir copie os controles usados no formulário form1.cs e altere a cor de fundo para outra cor para diferenciar os dois formulários.
Altere o nome do Button para btnThreadSegura e sua propriedade Text para : "Usando Threads - A maneira segura"
Veja o leiaute do novo formulário abaixo:
No evento Click do botão de comando inclua o código abaixo:
private void btnThreadSegura_Click(object sender, EventArgs e)
{
Thread th = new Thread(new ThreadStart(this.Thread_Segura));
th.Start();
txtTexto.Text = "Texto inserido pela Thread Principal.";
}
|
A seguir digite o código abaixo na rotina Thread_Segura:
private void Thread_Segura()
{
Thread.Sleep(2000);
string texto = "Texto Escrito de forma não segura pela Thread em segundo plano.";
if (this.txtTexto.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(DefinirTexto);
this.Invoke(d, new object[] { texto + " (Invoke)" });
}
else
{
this.txtTexto.Text = texto + " (No Invoke)";
}
}
|
Agora defina o seguinte código para a rotina DefinirTexto:
private void DefinirTexto(string texto)
{
this.txtTexto.Text = texto;
}
|
E finalmente declare o delegado abaixo no início do formulário:
delegate void SetTextCallback(string texto); |
Antes de executar altere a classe Program.cs conforme abaixo para executar o formulário form2.cs do projeto:
[STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form2()); } |
Agora executando o projeto teremos:
1- Na apresentação do formulário:
2- Após dois segundos a nova thread será executada:
Não ocorrerá nenhum erro se aplicarmos os conceitos básicos no tratamento de threads para execução de forma segura em formulários .
Cada formulário Windows possui uma propriedade InvokeRequired que retorna false se a thread atual estiver na fila de mensagens e um método Invoke o qual torna possível enfileirar o delegado com parâmetros na fila de mensagem do controle.
Como o delegado é chamado diretamente da fila de mensagens não ocorrem problemas com a thread.
Pegue o projeto completo aqui: Usando_Threads.zip
João 4:23 Mas a hora vem, e agora é, em que os verdadeiros adoradores adorarão o Pai em espírito e em verdade; porque o Pai procura a tais que assim o adorem.
João 4:24 Deus é Espírito, e é necessário que os que o adoram o adorem em espírito e em verdade.
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
|
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências: