INTRODUÇÃO:

  Muitas vezes, quando desenvolvemos ou usamos algum tipo de software, encontramos uma certa “demora” na execução de tarefas, pois quando o usuário executa algum formulário que processa muitas informações, esse formulário fica travado até que execute a tarefa e ainda impede que o usuário acesse outra parte do programa.   

  Para empresas ou programadores que desejam vender seus softwares isso acaba sendo deselegante, o usuário quer algo que atenda suas necessidades, seja rápido, e sempre esteja disponível quando precisar.

  Neste artigo você aprenderá como criar uma thread em paralelo usando o componente BackgroundWorker, assim quando o programa tiver que realizar alguma operação muito demorada a thread em segundo plano irá processar as informações e depois que concluir notificará a thread principal. Consequentemente o programa não ficará travado e será possível executar outras tarefas.

 

AGORA VAMOS COMEÇAR

  Estarei utilizando o C# Express para criar este projeto, então abra o C# e comece um novo projeto do tipo WindowsApplication, dê um nome qualquer e depois clique em OK.

  Agora acione a ToolBox e arraste para o Form1 os seguintes componentes: um DataGridView, um Button, e o BackgroundWorker. Adicione também um segundo Form.

Imagem

  O próximo passo é entrar no código do Form1 e certificar que ele esteja utilizando os namespaces:

using System.Data e  using System.Data.SqlClient, se não estiver você deve incluí-los.


Imagem

  O passo seguinte é importar um banco de dados para o projeto, então se você já tem um banco de dados, importe ele para o projeto, se não crie um novo. Nesta aplicação eu irei utilizar um banco de dados que criei no SQl Server, assim vou aproveitar para ensinar um macete que muita gente tem dúvida.

  Depois que o banco já tiver sido importado, volte para o código do Form1 e numa parte publica do código declare uma variável do tipo DataSet e uma String de conexão.

public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();         

        }
 

private DataSet ds;

public string Conexao = "Data Source=.\\SQLEXPRESS;AttachDbFilename=" + Environment.CurrentDirectory + "\\AquiTem_DataBase.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";

        /*  Esta é dica que eu gostaria de mostrar, a string de conexão pega o banco de dados de dentro do diretório \bin\Debug, então não importa onde você jogue seu projeto a string de conexão irá pegar seu banco de dados.        

     Logo depois do Environment.CurrentDirectory + , você deve colocar \\nome_do_banco.mdf, se seu banco estiver dentro do bin\Debug, agora se ele

estiver dentro de outra pasta no diretório bin\Debug basta colocar \\nome_dapasta\\nome_do_banco.mdf;IntegratedSecurity=True;Connect Timeout=30...

        */


 Se estiver retornando algum erro (na executção do programa) de que não foi encontrado o banco de dados, pode ser que a pasta padrão do projeto esteja configurada para bin\Release, se isso acontecer é só ir no Solution Explorer-->clicar no nome do projeto com o botão direito-->Properties-->Build e mudar para bin\Debug.

="

  Bom, continuando, entre no Events do backgroundWorker1, ele possuí 3 eventos escolha o DoWork, e coloque este código:


private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)

        {         

            SqlConnection conn = new SqlConnection(Conexao); // A variável conn é do tipo SqlConnection e tem como parâmetro a string de conexão.


for (int i = 0; i < 30; i++) // Se este Loop for executado rapidamente aumente o número de loops.

 {

            SqlCommand  cmd = new SqlCommand ("INSERT INTO Funcionario (CodFunc,Nome) VALUES (" + i + ",'Teste')",conn);

            /* O loop vai fazer o SqlCommand inserir 30 valores no banco de dados que nós importamos, o objetivo disso é mostrar uma operação que gasta muito tempo, e que enquanto ele está executando esta ação nesta thread  em paralelo você pode chamar o Form2, porque o Form1 não esta travado.

            */


            try

            {

                conn.Open();

                cmd.ExecuteNonQuery();

            }

 

            catch (Exception ex)

            {

                MessageBox.Show("Erro" + ex.Message);

            }

 

            finally { conn.Close(); }

            }
 

        }


  Obs: Não esqueça de trocar a sintaxe do SqlCommand, lembre-se que nós estamos usando banco de dados diferentes, e outra coisa importante que eu ainda não mencionei, nesta thread você não pode criar funções que carregam interfaces, por exemplo: você não pode carregar os dados do banco e depois preencher o DataGridView, isto é função da thread principal.

  Vamos para o próximo passo, volte para o Events do backgroundWorker1 e entre no RunWorkerCompleted, agora sim podemos carregar interfaces, este evento notifica a thread principal que a thread em paralelo está completa.

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

        {

            SqlConnection conn = new SqlConnection(Conexao);

            SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Funcionario", conn);          

            ds = new DataSet();

            da.Fill(ds); // Preencho o DataSet com o SqlDataAdapter           

            dataGridView1.DataSource = ds.Tables[0]; // Agora é exibido no DataGridView as informações do banco

        }

 


  Agora que já colocamos os códigos nos eventos do backgroundWorker1 só falta aciona-los, então no evento Load do Form1 coloque isto:

private void Form1_Load(object sender, EventArgs e)

        {

            backgroundWorker1.RunWorkerAsync();

            // Quando o programa for executado a thread já será executada

        }


  Tudo o que falta é colocarmos o código do Button1, nele apenas colocaremos o código para chamar o Form2. Então ficará assim:


private void button1_Click(object sender, EventArgs e)

        {

            Form2 f = new Form2();

            f.Show();

        }

  Finalmente o programa está pronto agora vamos executá-lo, note que quando o Form1 é carregado ele está inserindo informações no banco de dados, normalmente ele ficaria travado até terminar de fazer isso, mas se você clicar no Button1 ele chamará o Form2 e continuará executando a ação sem interferir no desempenho do programa.

 

CONCLUSÃO:

  Neste artigo foi criado um programa básico para demonstrar como uma thread pode aumentar o desempenho de um programa, quanto ao banco de dados é um assunto que é muito abordado na área de programação então não quis entrar em muitos detalhes, mas neste exemplo poderia ser usado um banco feito no Access.

Autor:

Geisson Pires da Silva

Técnico em Informática – Etec Pedro Ferreira Alves