none
Exibir um progressbar com porcentagem real de um BackgroundWorker RRS feed

  • Pergunta

  • Boa noite amigos,

    Como posso exibir um PROGRESSBAR com contagem real de tempo de uma determinada função?

    Eu estou executando uma função através de um BackgroundWorker e quero exibir um progressbar enquanto o processo é finalizado.

    MyCode:

            public void VerificarVersao()
            {
                   // AQUI FICA MINHA FUNÇÃO!
            }

    BackgroundWorker:

            private void bgWorkerVerificarVersao_DoWork(object     sender, DoWorkEventArgs e)
            {
                VerificarVersao();
            }

    Botão que inicia a verificação:

            private void btVerificarVersao_Click(object sender, EventArgs e)
            {
                btVerificarVersao.Enabled = false;
                btFechar.Enabled = false;
                bgWorkerVerificarVersao.RunWorkerAsync();
            }

    Amigos, preciso de uma ideia pra fazer o progressbar, estou utilizando imagens .GIF e creio que pesam muito o processo. Obrigado à todos desde já,

    Bom final de semana.

    domingo, 2 de outubro de 2016 00:33

Respostas

  • Voce está fazendo de forma incorreta, o While() que carregaria as informações do progressBar e contaria o total do percentual, POREM voce está usando datareader e ele nao retorna a quantidade total de linhas que ocorreu no select, a nao ser que voce use um Count(*) na sua query, ou ao invez disso voce pode usar a classe DataTable que voce pode recuperar a quantidade de linhas que teve no select com a propriedade Rows. Tente algo parecido com isso

    private void button1_Click(object sender, EventArgs e)
            {
                System.Threading.Thread _thread = new System.Threading.Thread(BackupSQL);
                _thread.Start();
            }
    
            public void BackupSQL()
            {
                DataTable _dt = new DataTable();
    
                try
                {
                    List<string> dbs = new List<string>();
                    
                    using (var conn = new SqlConnection("Server=.\\SQLEXPRESS;Database=master;Trusted_Connection=True;"))
                    {
                        
                        using (var da = new SqlDataAdapter("SELECT * from FOO",conn))
                        {
                            da.Fill(_dt);
                            
                            if (_dt.Rows.Count >0)
                            {
                                double _linhas = Convert.ToDouble(_dt.Rows.Count -1);
    
                                progressBar1.BeginInvoke((MethodInvoker)delegate { progressBar1.Maximum = Convert.ToInt32(_linhas); });
    
                                for(int i = 0;i <= _linhas;i++)                            
                                {
                                    label1.BeginInvoke((MethodInvoker)delegate { label1.Text = Math.Round(((i / _linhas) * 100)).ToString(); });
                                    progressBar1.BeginInvoke((MethodInvoker)delegate { progressBar1.Value = i; });
                                    System.Threading.Thread.Sleep(100);
                                    dbs.Add(_dt.Rows[i].ToString());
                                }
                            }
    
                        }
                    }
                }
                finally
                {
                }
            }



    Eduardo Bicudo Junior


    segunda-feira, 3 de outubro de 2016 02:25

Todas as Respostas

  • Olá,

    Olha esses exemplos aqui:

    http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo

    https://social.msdn.microsoft.com/Forums/en-US/9b3aef3e-b698-4aa9-a1d8-50fe2cf24927/how-to-use-progress-bar-in-backgroundworker?forum=csharplanguage

    https://www.dotnetperls.com/progressbar

    Obviamente que nesses exemplos eles estão usando um contador qualquer para simular o progresso da barra, mas você pode trabalhar com números reais, por exemplo se estiver lendo/processando 10 arquivos, após processar o primeiro, você terá 10% da sua progressbar e assim por diante.

    Valeu!


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    André Secco
    Microsoft MSP & MSDN Tech Advisor
    Blog: http://andresecco.com.br
    GitHub: http://github.com/andreluizsecco
    Twitter: @andre_secco

    domingo, 2 de outubro de 2016 02:34
  • Amigo, com esses exemplo não consegui fazer o que estou precisando. O progressbar está começando após concluir a função, preciso que ele mostre a porcentagem da função, para um acompanhamento exato do processo! 

    Tem alguma outra forma de conseguir fazer isso? :/

    Obrigado.

    domingo, 2 de outubro de 2016 05:47
  • Só voce ir incrementando a propriedade value do controle, e exibindo num label o percentual através de um calculo matematico simples.

    private void Carrega()
            {
                double _total = 1000;
                //seta os valores que iremos trabalhar dentro das propriedados do progressbar
                this.progressBar1.Minimum = 0;
                this.progressBar1.Maximum = Convert.ToInt32(_total);
    
                for (int i = 0; i <= _total; i++)
                {
                    //calculo responsavel pelo percentual da operaço
                    this.label1.Text = Math.Round(((i / _total) * 100)).ToString();
                    
                    this.progressBar1.Value = i;
                    System.Threading.Thread.Sleep(100);
                }
            }


    Eduardo Bicudo Junior

    domingo, 2 de outubro de 2016 18:28
  • Boa noite amigo,

    Chamei esse método na função do BackgroundWorker, mas ele carrega primeiro o progressbar, depois faz a operação! :/

    O que faço? 

            #region Carregarpb()
            private void Carregarpb()
            {
                double _total = 1000;
                // Seta os valores que iremos trabalhar dentro das propriedades do progressbar
                progressBar1.BeginInvoke((MethodInvoker)delegate { progressBar1.Minimum = 0; progressBar1.Maximum = Convert.ToInt32(_total); });
    
                for (int i = 0; i <= _total; i++)
                {
                    //Calculo responsavel pelo percentual da operação
                    label1.BeginInvoke((MethodInvoker)delegate { label1.Text = Math.Round(((i / _total) * 100)).ToString(); });
    
                    progressBar1.BeginInvoke((MethodInvoker)delegate { progressBar1.Value = i; });
    
                    System.Threading.Thread.Sleep(100);
                }
            }
            #endregion
            #region BackupSQL()
            public void BackupSQL()
            {
                try
                {
                    Carregarpb(); // AQUI CHAMO ELE!
                    List<string> dbs = new List<string>();
                    SqlDataReader reader;
                    using (var conn = new SqlConnection(connStringSQL))
                    {
                        using (var cmd = new SqlCommand("SELECT name FROM master.dbo.sysdatabases WHERE name NOT IN ('master','tempdb','model','msdb','ReportServer','ReportServerTempDB')"))
                        {
                            conn.Open();
                            cmd.Connection = conn;
                            cmd.CommandType = CommandType.Text;
                            reader = cmd.ExecuteReader();
                            while (reader.Read())
                            { dbs.Add(reader.GetString(0)); }
                        }


    domingo, 2 de outubro de 2016 22:42
  • Voce está fazendo de forma incorreta, o While() que carregaria as informações do progressBar e contaria o total do percentual, POREM voce está usando datareader e ele nao retorna a quantidade total de linhas que ocorreu no select, a nao ser que voce use um Count(*) na sua query, ou ao invez disso voce pode usar a classe DataTable que voce pode recuperar a quantidade de linhas que teve no select com a propriedade Rows. Tente algo parecido com isso

    private void button1_Click(object sender, EventArgs e)
            {
                System.Threading.Thread _thread = new System.Threading.Thread(BackupSQL);
                _thread.Start();
            }
    
            public void BackupSQL()
            {
                DataTable _dt = new DataTable();
    
                try
                {
                    List<string> dbs = new List<string>();
                    
                    using (var conn = new SqlConnection("Server=.\\SQLEXPRESS;Database=master;Trusted_Connection=True;"))
                    {
                        
                        using (var da = new SqlDataAdapter("SELECT * from FOO",conn))
                        {
                            da.Fill(_dt);
                            
                            if (_dt.Rows.Count >0)
                            {
                                double _linhas = Convert.ToDouble(_dt.Rows.Count -1);
    
                                progressBar1.BeginInvoke((MethodInvoker)delegate { progressBar1.Maximum = Convert.ToInt32(_linhas); });
    
                                for(int i = 0;i <= _linhas;i++)                            
                                {
                                    label1.BeginInvoke((MethodInvoker)delegate { label1.Text = Math.Round(((i / _linhas) * 100)).ToString(); });
                                    progressBar1.BeginInvoke((MethodInvoker)delegate { progressBar1.Value = i; });
                                    System.Threading.Thread.Sleep(100);
                                    dbs.Add(_dt.Rows[i].ToString());
                                }
                            }
    
                        }
                    }
                }
                finally
                {
                }
            }



    Eduardo Bicudo Junior


    segunda-feira, 3 de outubro de 2016 02:25
  • Caro Eduardo, boa noite.

    Não consegui implementar e fazer funcionar o código. Essa é minha função completa, que é chamada no BackgroundWorker_Work, através do (RunWorkerAsync) no botão Realizar Backup. O que posso fazer?

                try
                {
                    List<string> dbs = new List<string>();
                    SqlDataReader reader;
                    using (var conn = new SqlConnection(connStringSQL))
                    {
                        using (var cmd = new SqlCommand("SELECT name FROM master.dbo.sysdatabases WHERE name NOT IN ('master','tempdb','model','msdb','ReportServer','ReportServerTempDB')"))
                        {
                            conn.Open();
                            cmd.Connection = conn;
                            cmd.CommandType = CommandType.Text;
                            reader = cmd.ExecuteReader();
                            while (reader.Read())
                            { dbs.Add(reader.GetString(0)); }
                        }
                        foreach (string db in dbs)
                        {
                            using (var cmdBkp = new SqlCommand("BACKUP DATABASE " + db + " TO DISK = '" + txtDestinoSQL.Text + "\\" + db +
                            "-" + DateTime.Now.ToString("HHmmss-ddMMyyyy") + ".bak'"))
                            {
                                try
                                {
                                    cmdBkp.Connection = conn;
                                    cmdBkp.CommandType = CommandType.Text;
                                    cmdBkp.CommandTimeout = 300;
                                    reader.Close();
                                    cmdBkp.ExecuteNonQuery();
    
                                    btRealizarBackup.BeginInvoke((MethodInvoker)delegate
                                    { btRealizarBackup.Enabled = false; btRealizarBackup.Text = "Realizar Backup"; });
    
                                    txtLog.BeginInvoke((MethodInvoker)delegate
                                    { txtLog.Text = "Backup realizado com sucesso, o sistema já pode ser atualizado."; });
    
                                    pbRealizarBackupOK.BeginInvoke((MethodInvoker)delegate
                                    { pbRealizarBackupOK.Visible = true; });
                                    lbBackupRealizadoOK.BeginInvoke((MethodInvoker)delegate
                                    { lbBackupRealizadoOK.Visible = true; });
    
                                    pbRealizarBackup.BeginInvoke((MethodInvoker)delegate
                                    { pbRealizarBackup.Visible = false; });
    
                                    btBaixarAtualizacao.BeginInvoke((MethodInvoker)delegate
                                    { btBaixarAtualizacao.Enabled = true; });
    
                                }
                                catch (Exception ex)
                                {
                                    pbRealizarBackup.BeginInvoke((MethodInvoker)delegate
                                    { pbRealizarBackup.Visible = false; });
    
                                    txtLog.BeginInvoke((MethodInvoker)delegate
                                    { txtLog.Text = ex.Message; });
    
                                    MessageBox.Show("Ops! Ocorreu um erro ao tentar realizar o backup de todos os bancos de dados. " +
                                    "Verifique se possui espaço em disco. Caso o problema persista, entre em contato com o suporte técnico.",
                                    "Aviso do Sistema", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                                
                                    conn.Close();
                                    cmdBkp.Dispose();
                                    return;
                                }
                            }
                        }
                        conn.Close();
                    }
                }
                catch (Exception ex)
                { MessageBox.Show(ex.Message); }
            }

    Obrigado

    segunda-feira, 3 de outubro de 2016 03:15
  • Siga o exemplo que eu dei acima que dá certo, voce precisa usar o DataTable ao inves do SqlDataReader pra retornar as linhas e trabalhar como north pro percentual e para o progressbar

    Eduardo Bicudo Junior

    segunda-feira, 3 de outubro de 2016 11:17