C# - Gerenciando Processos e Threads em Windows Forms - II

 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:


José Carlos Macoratti