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

时间:2011-04-23 01:19:39

标签: c# wpf

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

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

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

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

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

 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);

             }
       }

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

感谢。

1 个答案:

答案 0 :(得分:6)

问题在于:

  

上传由单独的线程完成,并且   进度条以单独的形式显示   子线程调用时   上传开始

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

更好的方法是在 main 主题中创建进度条表单。

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

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

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()
         {
 // ...