I have an application where I am uploading a file in blocks. My front end is WPF and I have a progress bar to show file upload progress (upload is done by separate thread, and the progress bar is in a separate form invoked by the child thread when uploading starts).
I found the total number of blocks in the file to set the maximum property of the progress bar.
Now for each block uploaded I increment the value of progress bar by 1.
But to my surprise, the progress bar starts to increment but never completes ( it stops showing progress after few blocks ).
Here is code for the thread responsible for uploading files:
System.Threading.Thread thread = new Thread(
new ThreadStart(
delegate()
{
// show progress bar - Progress is the name of window containing progress bar
Progress win = new Progress();
win.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
win.Show();
// find number of blocks
long BlockSize = 4096;
FileInfo fileInf = new FileInfo(filename);
long FileSize = fileInf.Length;
long NumBlocks = FileSize / BlockSize;
//set the min and max for progress bar
win.Dispatcher.Invoke(
new Action(
delegate()
{
win.progressBar1.Minimum = 0;
win.progressBar1.Maximum = NumBlocks;
}
), System.Windows.Threading.DispatcherPriority.Render);
//upload file
while (true)
{
// code to upload the file
win.Dispatcher.Invoke(
new Action(
delegate()
{
win.progressBar1.Value += 1;
}
), System.Windows.Threading.DispatcherPriority.Render);
}
}
Can someone help me analyze why is this happening.
Thanks.
Here’s the issue:
If that means your child thread created the form, then that’s the problem. Your child thread might be updating the progress bar values, but this will just invalidate the display, and not necessarily refresh the display. When a control’s display is invalidated, it simply records that it must redraw it’s display the next time it gets a chance. A refresh is when the control actually gets to render to the screen.
A better approach is to create the progress bar form in the main thread.
Your worker thread can then update the status, and your main thread will refresh the display.
One thing to remember: if you’re updating a control that was created in a different thread, you must do so via the control’s dispatcher.
Edit after seeing the code
All you need to do is move the creation of the progress variable so that it is instantiated by the main thread before the worker thread is created.