BACKGROUNDWORKER + PROGRESSBAR
Boa noite.
Nobres colegas, tenho uma aplicação Windows Forms com C#. Essa aplicação possui um form principal, e vários outros forms são abertos dentro desse (MDI Container) esses [Ô]subforms[Ô] são charts e datagrids. Alguns deles demoram para carregar e dão a sensação ao usuario que a aplicação travou. Quero colocar uma ProgressBar no form principal para mostrar ao usuário que o form solicitado por ele está sendo carregado.
Pelo que pesquisei isso é feito com BackgroundWorker, pesquisei algo na internet, até fiz uma aplicação que há um botão e uma ProgressBar que enche ao apertar o botão, mas ainda não entendi como fazer o codigo fazendo o set Min e Max da progressbar e vincular o tempo do trabalho a ser realizado com o preenchimento da progress bar, como no exemplo a função acima Carregar(), a função preenche um chart, quero que o tempo de preenchimento do chart fosse acompanhado pela progress, e depois de devidamente carregado o form seja aberto, ou mostrado. é possivel?
Nobres colegas, tenho uma aplicação Windows Forms com C#. Essa aplicação possui um form principal, e vários outros forms são abertos dentro desse (MDI Container) esses [Ô]subforms[Ô] são charts e datagrids. Alguns deles demoram para carregar e dão a sensação ao usuario que a aplicação travou. Quero colocar uma ProgressBar no form principal para mostrar ao usuário que o form solicitado por ele está sendo carregado.
private void Carregar()
{
try
{
using (SqlCommand Cmd01 = new SqlCommand())
{
Cmd01.CommandText = Classes.Querrys.OS_Mes;
//Cria Parametros para substituir na Querry
Cmd01.Parameters.Add([Ô]@data1[Ô], SqlDbType.DateTime);
Cmd01.Parameters[[Ô]@data1[Ô]].Value = String.Format([Ô]{0:yyyy/MM/dd} {1}[Ô], this.dtpIni1.Value, [Ô]00:00:00[Ô]);
Cmd01.Parameters.Add([Ô]@data2[Ô], SqlDbType.DateTime);
Cmd01.Parameters[[Ô]@data2[Ô]].Value = String.Format([Ô]{0:yyyy/MM/dd} {1}[Ô], this.dtpFim1.Value, [Ô]23:59:59[Ô]);
//Exibe os dados no Chart
DataView Grafico = new DataView(Classes.Conexao.GetBuscaSigma(Cmd01));
chtOrdem.Series[0].Points.DataBindXY(Grafico, [Ô]Mes[Ô], Grafico, [Ô]Abertas[Ô]);
chtOrdem.Series[1].Points.DataBindXY(Grafico, [Ô]Mes[Ô], Grafico, [Ô]Fechadas[Ô]);
chtOrdem.ChartAreas[[Ô]ChartArea1[Ô]].AxisX.MajorGrid.Enabled = false;
chtOrdem.ChartAreas[[Ô]ChartArea1[Ô]].AxisY.MajorGrid.Enabled = false;
chtOrdem.ChartAreas[[Ô]ChartArea1[Ô]].AxisY.LabelStyle.Enabled = false;
chtOrdem.ChartAreas[[Ô]ChartArea1[Ô]].AxisX.Interval = 1;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Pelo que pesquisei isso é feito com BackgroundWorker, pesquisei algo na internet, até fiz uma aplicação que há um botão e uma ProgressBar que enche ao apertar o botão, mas ainda não entendi como fazer o codigo fazendo o set Min e Max da progressbar e vincular o tempo do trabalho a ser realizado com o preenchimento da progress bar, como no exemplo a função acima Carregar(), a função preenche um chart, quero que o tempo de preenchimento do chart fosse acompanhado pela progress, e depois de devidamente carregado o form seja aberto, ou mostrado. é possivel?
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 0; i < 101; i++)
{
worker.ReportProgress(i);
System.Threading.Thread.Sleep(1000);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
worker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
worker.RunWorkerAsync();
}
Você não vai conseguir fazer isso assim.
Primeiro não existe como pegar o progresso de uma função, é a própria função (seu código) que tem que saber informar o progresso, e em alguns casos, como por exemplo dependendo de como se faz o acesso ao banco de dados pode não ter como calcular este progresso.
Outra coisa é que não só o código do progresso teria que ficar no backgroundworker, mas todo o código que demora para rodar deveria ficar nele, só que o problema ai é que nenhum código rodando fora do thread que criou o form deve modificar seus controles pois isso pode causar um comportamento totalmente inesperado nos controles, por exemplo eu já vi um caso em que um DataGrid era preenchido em um thread e com isso sumiam os column headers e algumas colunas não mostravam os dados.
Acho que o mais fácil seria exibir uma mensagem de aguarde enquanto você processa os dados.
Primeiro não existe como pegar o progresso de uma função, é a própria função (seu código) que tem que saber informar o progresso, e em alguns casos, como por exemplo dependendo de como se faz o acesso ao banco de dados pode não ter como calcular este progresso.
Outra coisa é que não só o código do progresso teria que ficar no backgroundworker, mas todo o código que demora para rodar deveria ficar nele, só que o problema ai é que nenhum código rodando fora do thread que criou o form deve modificar seus controles pois isso pode causar um comportamento totalmente inesperado nos controles, por exemplo eu já vi um caso em que um DataGrid era preenchido em um thread e com isso sumiam os column headers e algumas colunas não mostravam os dados.
Acho que o mais fácil seria exibir uma mensagem de aguarde enquanto você processa os dados.
Obrigado pela Resposta Ocelot!
O que me disseram é que eu não colocaria no backgroundworker o processo completo, como por exemplo a consulta no banco, que não parece ser o que está demorando. Quado rodo a querry no ManagementStudio é bem rapida a consulta, o que parece demorar é o preenchimento da tela (Chart ou Datagrid). O que tinham me instruido é fazer o Set Min o gatilho da função e o set Max a [Ô]população[Ô] da ultima linha. Existe a possibilidade de fazer assim?
Outra coisa, alguns forms que demoram muito aparece a mensagem de [Ô]Não Respondendo[Ô] mas se o usuario esperar ele carrega, sei que há como aumentar o tempo para que esse erro não ocorra, mas não sei a sintaxe, poderia me ajudar, como no exemplo que dei acima?
O que me disseram é que eu não colocaria no backgroundworker o processo completo, como por exemplo a consulta no banco, que não parece ser o que está demorando. Quado rodo a querry no ManagementStudio é bem rapida a consulta, o que parece demorar é o preenchimento da tela (Chart ou Datagrid). O que tinham me instruido é fazer o Set Min o gatilho da função e o set Max a [Ô]população[Ô] da ultima linha. Existe a possibilidade de fazer assim?
Outra coisa, alguns forms que demoram muito aparece a mensagem de [Ô]Não Respondendo[Ô] mas se o usuario esperar ele carrega, sei que há como aumentar o tempo para que esse erro não ocorra, mas não sei a sintaxe, poderia me ajudar, como no exemplo que dei acima?
O que eu gostaria é de criar algo para que o usuário saiba que a tela está sendo carregada e que a aplicação não travou. No meu entendimento, fazer isso pelo preenchimento da tela seria algo simples, não estou considerando a consulta no banco, mas sim o preenchimento do chart ou do grid. Tem algo que eu possa fazer nesse sentido?
Não sei se é exatamente o que eu preciso, mas para ajudar a explicar a minha necessidade, o link abaixo [Ô]aparenta[Ô] ser quase o que eu preciso...
http://code-programmming.blogspot.com.br/2013/12/backgroundworker-and-progress-bar-c.html
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Quando o usuário abrir o form, a barra começa a ser carregada mostrando ao usuário que a sua solicitação está sendo executada.
http://code-programmming.blogspot.com.br/2013/12/backgroundworker-and-progress-bar-c.html
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Quando o usuário abrir o form, a barra começa a ser carregada mostrando ao usuário que a sua solicitação está sendo executada.
Porque você não usa uma GIF animada dentro de uma Picture, ao invés de uma barra de progresso?
Você pode procurar na NET, sempre se encontra.
Você deixa ela visÃvel quando iniciar o carregamento, aÃ, a GIF fica rodando, piscando, por exemplo, enquanto você carrega tudo o que tem que carregar. Quando terminar, você torna ela invisÃvel. Assim, você não precisa calcular o tempo que vai demorar para carregar tudo.
Até mais.
Você pode procurar na NET, sempre se encontra.
Você deixa ela visÃvel quando iniciar o carregamento, aÃ, a GIF fica rodando, piscando, por exemplo, enquanto você carrega tudo o que tem que carregar. Quando terminar, você torna ela invisÃvel. Assim, você não precisa calcular o tempo que vai demorar para carregar tudo.
Até mais.
A ideia é legal, tem algum link para me indicar para estudar a sintaxe de construção do conceito.
Rogério
A utilização deste tipo de conceito é um pouco complicada, mais não é impossÃvel.
Basicamente um progressbar precisa saber quando irá iniciar e quando irá finalizar o processo, quando isto está vinculado à uma consulta, fica meio difÃcil de se aplicar.
Você pode utilizar o que o PERCIFILHO disse, utilizar um gif animado, isto já da uma mudada no visual da tela. Para fugir um pouco de se utilizar uma Thread, você pode utilizar o Application.DoEvents para exibir o progresso.
Estou anexando um exemplo para você.
A utilização deste tipo de conceito é um pouco complicada, mais não é impossÃvel.
Basicamente um progressbar precisa saber quando irá iniciar e quando irá finalizar o processo, quando isto está vinculado à uma consulta, fica meio difÃcil de se aplicar.
Você pode utilizar o que o PERCIFILHO disse, utilizar um gif animado, isto já da uma mudada no visual da tela. Para fugir um pouco de se utilizar uma Thread, você pode utilizar o Application.DoEvents para exibir o progresso.
Estou anexando um exemplo para você.
Boa noite.
Eu encontrei alguns modelos usando BACKGROUNDWORKER, mas não consegui adequar os modelos na minha aplicação, as maiores dúvidas era vincular o preenchimento da tela com a PROGRESSBAR.
Pensei em fazer como o colega sugeriu, inserir uma GIF animada para mostrar o progresso, deve ser almo mais facil de fazer, mas ainda tenho dúvidas para vincular o gatinho entre o momento de iniciar a GIF e tirar a mesma após a tela ser preenchida.
Os colegas teriam algum modelo ou link para me indicar? Abaixo dou um exemplo da função que traz as informações.
Eu encontrei alguns modelos usando BACKGROUNDWORKER, mas não consegui adequar os modelos na minha aplicação, as maiores dúvidas era vincular o preenchimento da tela com a PROGRESSBAR.
Pensei em fazer como o colega sugeriu, inserir uma GIF animada para mostrar o progresso, deve ser almo mais facil de fazer, mas ainda tenho dúvidas para vincular o gatinho entre o momento de iniciar a GIF e tirar a mesma após a tela ser preenchida.
Os colegas teriam algum modelo ou link para me indicar? Abaixo dou um exemplo da função que traz as informações.
private void Carregar()
{
try
{
using (SqlCommand Cmd01 = new SqlCommand())
{
Cmd01.CommandText = Classes.Querrys.OS_Mes;
//Cria Parametros para substituir na Querry
Cmd01.Parameters.Add([Ô]@data1[Ô], SqlDbType.DateTime);
Cmd01.Parameters[[Ô]@data1[Ô]].Value = String.Format([Ô]{0:yyyy/MM/dd} {1}[Ô], this.dtpIni1.Value, [Ô]00:00:00[Ô]);
Cmd01.Parameters.Add([Ô]@data2[Ô], SqlDbType.DateTime);
Cmd01.Parameters[[Ô]@data2[Ô]].Value = String.Format([Ô]{0:yyyy/MM/dd} {1}[Ô], this.dtpFim1.Value, [Ô]23:59:59[Ô]);
//Exibe os dados no Chart
DataView Grafico = new DataView(Classes.Conexao.GetBuscaSigma(Cmd01));
chtOrdem.Series[0].Points.DataBindXY(Grafico, [Ô]Mes[Ô], Grafico, [Ô]Abertas[Ô]);
chtOrdem.Series[1].Points.DataBindXY(Grafico, [Ô]Mes[Ô], Grafico, [Ô]Fechadas[Ô]);
chtOrdem.ChartAreas[[Ô]ChartArea1[Ô]].AxisX.MajorGrid.Enabled = false;
chtOrdem.ChartAreas[[Ô]ChartArea1[Ô]].AxisY.MajorGrid.Enabled = false;
chtOrdem.ChartAreas[[Ô]ChartArea1[Ô]].AxisY.LabelStyle.Enabled = false;
chtOrdem.ChartAreas[[Ô]ChartArea1[Ô]].AxisX.Interval = 1;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Faça seu login para responder