I have a process in which I make evaluations of the employees, to process the strikeouts, in the form of X number of employees that are displayed, the user can select the ones they want to process. While it is processing, I must show the Progress and percentage that the process is going through.
Problem: The progressBar
increase goes but labelPorcentaje
it does not increase, it only shows 100% at the end of the process. The amount of data to process depends on the employees that the user selects, therefore, on occasions they can be few or many, I want to be able to appreciate the increase in progress during the process regardless of whether the data to be processed is few or many.
I have made a simple example to represent my problem:
private void btnEvaluar_Click(object sender, EventArgs e)
{
labelProgreso.Visible = true;
progressBar1.Visible = true;
int progreso = 0, porciento = 0, totalEmpleadosProcesar = 0;
for (int indice = 0; indice < 85; indice++) //Ciclo que representará los empleados seleccionados
{
totalEmpleadosProcesar = 85; //Total de Empleados que seleccionó el usuario
progreso++; //Aumentando el progreso
porciento = Convert.ToInt16(( ( (double)progreso / (double)totalEmpleadosProcesar ) * 100.00 )); //Calculo del porcentaje
reportarProgreso(100, porciento); //función que cargará la barra de progreso
//MessageBox.Show("Porciento: " + porciento);
}
MessageBox.Show("Completo...");
labelProgreso.Visible = false;
progressBar1.Visible = false;
}
Function that loads the ProgressBar:
private void reportarProgreso(int valorMaximo, int valor)
{
progressBar1.Step = 1;
progressBar1.Style = ProgressBarStyle.Continuous;
progressBar1.Minimum = 0;
progressBar1.Maximum = valorMaximo;
if (valor > valorMaximo)
{
labelProgreso.Text = "100%";
progressBar1.Value = valorMaximo;
}
else
{
labelProgreso.Text = Convert.ToString(valor) + "%";
progressBar1.Value = valor;
}
}
To fix it I tried to use Thread.Sleep(1000);
during the loop traversal, but still it doesn't show the percentage in thelabel
I don't want to use a
Thread.Sleep
because as I said if there are few employees it would work well, but if there are many and I have a set time for the Thread it would take a lot.
If I intervene each cycle interaction with a MessageBox
test if it shows me the percentage in the label
.
What am I doing wrong? What would be the correct way to represent the progress of a process?
Note : I don't care if the interface is still active during the process, that's why I haven't used Task
or BackGroundWorker
...
Environment: Visual Studio 2010 (WindowsForms) & .NET NetFramework 4.0
The problem is that your loop blocks the main thread of execution, preventing the label from being redrawed. To solve it I recommend using a BackgroundWorker.
First, define the
BackgroundWorker
in your form:Then in the button event, you set the
ProgressChanged
,DoWork
and eventsRunWorkerCompleted
and call their execution:Event
DoWork
(I've added oneSleep
to show progress):The event
ProgressChanged
where we update both theProgressbar
and theLabel
:Finally, the event
RunWorkerCompleted
that is executed when theBackgroundWorker
has finished: