简体   繁体   English

WPF进度条未显示正确的进度

[英]WPF Progress bar not showing correct progress

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). 我的前端是WPF,我有一个进度条来显示文件上传进度(上传是由单独的线程完成的,进度条是在上传开始时由子线程调用的单独表单)。

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. 现在,对于每个上传的块,我将进度条的值增加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: 这是问题所在:

upload is done by separate thread, and the progress bar is in a separate form invoked by the child thread when uploading starts 上传由单独的线程完成,进度条是在上传开始时由子线程调用的单独表单

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. 要记住的一件事是:如果要更新在不同线程中创建的控件,则必须通过控件的调度程序执行此操作。

var dispatcher = progressBar.Dispatcher;
dispatcher.BeginInvoke(new Action( () => { progressBar.Value = currentProgress }));


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. 您需要做的就是移动progress变量的创建,以便在创建工作线程之前由主线程实例化它。


 Progress win = new Progress(); win.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; win.Show(); System.Threading.Thread thread = new Thread( new ThreadStart( delegate() { // ... 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM