Progressbar and Backgroundworker in C#

Asked

Viewed 1,608 times

4

I’m creating an app with Firebird 2.5 in which I need her to read a file .sql with instructions to popular the database if it has not yet been done this process, because it is a little long and not sure how long it will take to complete it and the application does not stay "não respondendo" then I decided to add a ProgressBar with a BackgroundWorker, only that when adding them I am now getting the following error during the execution of the commands: Connection must be valid and open. Now if I run the application without using the ProgressBar and BackgroundWorker this error does not occur. This is the code I am making and the image of her screen working being that it comes to end without giving any error. I based this example on Devmedia: http://www.devmedia.com.br/backgrounworker-e-progressbar-exibindo-uma-barra-de-progresso-em-c/32127

using System;
using System.Data;
using System.Windows.Forms;
using Engebuilder.Library;
using Engebuilder.UI.Windows.General;
using Engebuilder.UI;
using Engebuilder.Data;
using System.Reflection;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using System.Text;

namespace GSD
{
    public partial class FomAux : Engebuilder.UI.Windows.General.DefaultForm
    {
        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

        public FomAux()
        {
            this.InitializeComponent();
            this.SetComponents(components);
        }

        private void FomAux_Load(object sender, System.EventArgs e)
        {
            timer.Interval = 10;
            timer.Enabled = true;
            timer.Tick += new EventHandler(Timer_Tick);
        }

        int contador = 0;

        private void Timer_Tick(object sender, System.EventArgs e)
        {
            try
            {
                contador += 1;

                if (contador >= 5)
                {
                    timer.Enabled = false;
                    contador = 0;

                    backgroundWorkerPopularBanco.RunWorkerAsync();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ocorreu um erro inesperado: \"" + ex.Message + "\"", "Atenção!", MessageBoxButtons.OK, MessageBoxIcon.Information);

                this.Close();
            }
        }


        private void backgroundWorkerPopularBanco_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            try
            {
                string diretorio = Directory.GetCurrentDirectory();
                string filePath = Path.Combine(diretorio, "SCRIPT.sql");

                if (File.Exists(filePath))
                {
                    string populouBanco = Engebuilder.Library.LDataAccess.GetDataToString("SELECT CONFIG_SISTEMA.CONF_SIS_POPULOUBANCO FROM CONFIG_SISTEMA");

                    if (populouBanco.Trim().Equals("") || populouBanco.Trim().Equals("N"))
                    {
                        StreamReader leitor = new StreamReader(filePath, Encoding.UTF7);
                        string comteudoArq = leitor.ReadToEnd();

                        string[] comando = comteudoArq.Trim().Split(new Char[] { '!' });

                        Int64 contador = 0;

                        foreach (string valor in comando)
                        {
                            contador++;

                            if (!valor.Trim().Equals(""))
                            {
                                Engebuilder.Library.LDataAccess.ExecuteCommand(valor.Trim());

                                //faz a thread dormir por "p" milissegundos a cada passagem do loop
                                //Thread.Sleep(p);

                                listBox.BeginInvoke(
                                    new Action(() =>
                                    {
                                        listBox.Items.Add("[ " + DateTime.Now.ToString() + " ] - Processo: " + contador.ToString() + " comcluído.");
                                        listBox.SelectedIndex = listBox.Items.Count - 1;
                                    }
                                ));
                            }
                        }

                        string sqlConfig = "INSERT INTO CONFIG_SISTEMA (CONF_SIS_POPULOUBANCO, CONF_SIS_DATA, CONFI_SIS_LOG) "
                        + " VALUES('S', '" + DateTime.Now.ToString().Replace("/", ".") + "', NULL)";
                        Engebuilder.Library.LDataAccess.ExecuteCommand(sqlConfig.Trim());

                        DialogResult result = MessageBox.Show("Configurações Concluídas com Sucesso!", "Atenção!", MessageBoxButtons.OK, MessageBoxIcon.Information);

                        if (result.Equals(DialogResult.OK))
                            this.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ocoreu um erro Realizar algumas Configurações: \"" + ex.Message + "\"", "Atenção!", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void backgroundWorkerPopularBanco_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            //Caso cancelado...
            if (e.Cancelled)
            {
                // reconfigura a progressbar para o padrao.
                ProgressBarPopularBanco.MarqueeAnimationSpeed = 0;
                ProgressBarPopularBanco.Style = ProgressBarStyle.Blocks;
                ProgressBarPopularBanco.Value = 0;

                //caso a operação seja cancelada, informa ao usuario.
                listBox.Items.Add("[ " + DateTime.Now.ToString() + " ] - Operação Cancelada pelo Usuário!");

                //limpa a label
                label1.Text = string.Empty;
            }
            else if (e.Error != null)
            {
                //informa ao usuario do acontecimento de algum erro.
                listBox.Items.Add("[ " + DateTime.Now.ToString() + " ] - Aconteceu um erro durante a execução do processo!");
                // reconfigura a progressbar para o padrao.
                ProgressBarPopularBanco.MarqueeAnimationSpeed = 0;
                ProgressBarPopularBanco.Style = ProgressBarStyle.Blocks;
                ProgressBarPopularBanco.Value = 0;
            }
            else
            {
                //informa que a tarefa foi concluida com sucesso.
                listBox.Items.Add("[ " + DateTime.Now.ToString() + " ] - Processos Concluidos com Sucesso!");
                //Carrega todo progressbar.
                ProgressBarPopularBanco.MarqueeAnimationSpeed = 0;
                ProgressBarPopularBanco.Style = ProgressBarStyle.Blocks;
                ProgressBarPopularBanco.Value = 100;
                label1.Text = ProgressBarPopularBanco.Value.ToString() + "%";
            }
        }
    }
}

inserir a descrição da imagem aqui

  • Where the error occurs?

  • I started to analyze a little more right the errors that are occurring here and it is exactly the following: 1º he is giving this error: "Connection must be Valid and open" by the check is as if he had requested the connection with bank, bank this unfortunately is Firebird 2.5. Now this only occurs when I run with Progressbar and Backgroundworker.

  • Removes the progressibar, puts an msg saying it will take a few minutes, hangs keyboard and mouse, I believe that in C# there is already a native function

  • As was shown an alternative in the comment above, I also tried to perform this procedure in which it actually blocks the mouse and keyboard, but soon after the same call the method that performs the Insert in the database not executed, as well as any other function of the system. To lock the mouse and keyboard I am following the information of this post: http://answall.com/questions/51973/block_keyboard_e-mouse-ou-impedeusuario-deixar janela-em-c#

  • 1

    Have you ever tried to put a breakpoint in those parts?

  • yes @Khaosdoctor with verrifiei error occurs precisely in the execution of SQL command where I receive msg: Connection must be valid and open and then it for the execution of the loop and throws another exception: Referência de objeto não definida para uma instância de um objeto..

  • Tried a debug to see which instance is null?

  • @Joaquimcaetanoteixeira, what is the behavior of your data access library Engebuilder.Library.LDataAccess, it closes the connection after execution, it allows transaction use? Transacting would be very good.

  • @Rodrigoreis actually can’t tell you with 100% certainty, but I think in 99% he closes the connection with each execution.

  • @And what about transactions? Still regarding the connection, is there any method in this library that allows you to get the open connection and is there any signature of the execution method that allows you to pass the open connection by reference? If so, maybe this is the way...

Show 5 more comments

1 answer

1

Caro Joaquim,

Among the many causes for this problem, I suppose it’s a winforms application, right? Typically these problems are related to thread execution (the backgroundworker is one of them...). Notice which winforms applications are in thread-safe, that is, the execution of a routine should begin ONLY if another routine is completed. When trying to perform routines in parallel bizarre messages usually happen, (when they didn’t happen before trying to use executions in parallel). Well, still it is possible to run routines in parallel through the use of TASK (a thread with a better abstraction level than the threads of earlier versions of .NET) Thus, they follow ways to better elucidate their problem

  1. Study on [Task Parallel]
  2. Thread-safe calls to winforms
  3. Perhaps try to change the block where you see string sqlConfig="...." into inside this.Invoke(new MethodInvoker(() =>{ sqlConfig="...." Engebuilder.Library.LDataAccess.ExecuteCommand(sqlConfig.Trim()); };
  4. Tip: Prefer XML to TXT file.(I went through several problems with it...) besides, the . NET has a wide range of methods for handling these files
  5. See this code to better understand:

    #region Thread Status da Conexao
    /// <summary>
    /// Lanca thread para verificação de conexao com banco de dados a cada 5s
    /// <para>Notifica caso conexão caia</para>
    /// </summary>
    private void ThreadConexao()
    {
        Task conexao = new Task(() =>
           {
               bool isconetado = true;
               try
               {
                   while (true)
                   {
                       //Verifica conexao com o banco de dados
                       isconetado = Connect();
                       //Todas as vezes que a rotina é executada
                       //o metodo MethoInvoker é acionado e direciona a chamada ao controle do formulario                           
                       if (isconetado)
                       {
                           this.Invoke(new MethodInvoker(() =>
                           {
                               //Exibir no rodape do form a informacao de conectado
                               label1.Text = "Conectado";
                              //Uma imagem contendo um simbolo de conectado
                               pictureBox1.Image = Properties.Resources.connect_style2;
                           }));
    
                       }
                       else
                       {
                           this.Invoke(new MethodInvoker(() =>
                           {
                               //Exibir no rodape do form a informacao de desconectado
                               label1.Text = "Desconectado";
                               //Uma imagem contendo um simbolo de desconectado
                               pictureBox1.Image = Properties.Resources.disconnect_style2;
    
                           }));
    
                       }
                       //A cada 5 segundos volta a fazer a verificação de conexao com o banco de dados
                       Thread.Sleep(5000);
                   }
    
               }
               catch (Exception) { }
    
    
           });
    
        conexao.Start();
    }
    
    
    
    #endregion
    

An example image

inserir a descrição da imagem aqui

Browser other questions tagged

You are not signed in. Login or sign up in order to post.