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

我有一个应用程序,我在块中上传文件。 我的前端是WPF,我有一个进度条来显示文件上传进度(上传是由单独的线程完成的,进度条是一个单独的表格,由子线程在上传开始时调用)。

我找到了文件中的块总数来设置进度条的最大属性。

现在,对于每个上传的块,我将进度条的值增加1。

但令我惊讶的是,进度条开始增加但从未完成(它在几个块之后停止显示进度)。

以下是负责上传文件的线程的代码:

  System.Threading.Thread thread = new Thread(
   新的ThreadStart(
         代表()
          {
               // show progress bar  -  Progress是包含进度条的窗口的名称
              进步胜利=新进展();
               win.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
               win.Show();

               //找到块数
              long BlockSize = 4096;
              FileInfo fileInf = new FileInfo(filename);
              long FileSize = fileInf.Length;
              long NumBlocks = FileSize / BlockSize;

              //设置进度条的最小值和最大值
              win.Dispatcher.Invoke(
                  新动作(
                     代表()
                      {
                             win.progressBar1.Minimum = 0;
                             win.progressBar1.Maximum = NumBlocks;                                                        
                      }
              ),System.Windows.Threading.DispatcherPriority.Render);

              //上传文件
             而(真)
              {

                       //上传文件的代码

                       win.Dispatcher.Invoke(
                          新动作(
                              代表()
                               {
                                  win.progressBar1.Value + = 1;
                               }
                       ),System.Windows.Threading.DispatcherPriority.Render);

              }
        }

有人可以帮我分析为什么会这样。

谢谢。

这是问题所在:

上传由单独的线程完成,进度条是在上传开始时由子线程调用的单独表单

如果这意味着你的子线程创建了表单,那就是问题所在。 您的子线程可能正在更新进度条值,但这将使显示无效 ,并且不一定刷新显示。 当控件的显示无效时 ,它只会记录下次有机会时必须重绘它的显示。 刷新是控件实际呈现到屏幕的时间。

更好的方法是在线程中创建进度条表单。

然后,您的工作线程可以更新状态,主线程将刷新显示。

需要记住的一件事是:如果要更新在不同线程中创建的控件,则必须通过控件的调度程序执行此操作。

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

看到代码后编辑

您需要做的就是移动progress变量的创建,以便在创建工作线程之前由主线程实例化它。


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