Usuário com melhor resposta
Exibir um progressbar com porcentagem real de um BackgroundWorker

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.
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
- Editado Eduardo xUni segunda-feira, 3 de outubro de 2016 02:31
- Marcado como Resposta Robson William SilvaModerator quarta-feira, 5 de outubro de 2016 12:01
Todas as Respostas
-
Olá,
Olha esses exemplos aqui:
http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo
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.
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- Sugerido como Resposta Alessandra F. Silva segunda-feira, 3 de outubro de 2016 11:39
-
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.
-
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
-
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)); } }
-
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
- Editado Eduardo xUni segunda-feira, 3 de outubro de 2016 02:31
- Marcado como Resposta Robson William SilvaModerator quarta-feira, 5 de outubro de 2016 12:01
-
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
-