0

如果你可以把它想象成一个加载栏:

for (int i = 0; i < r.Width / 2; i++) //Fills half the loading bar.
{         
    Rectangle rect = can.Children[3] as Rectangle; //getting the 3rd element of my Canvas
    if (rect != null)
     {
         rect.Fill = brush;
         rect.Width = i;
         Thread.Sleep(50);
     }
}

因此,应用程序不会显示添加其他矩形的进度。相反,它只是冻结了线程睡眠的总时间,当 for 循环完成时,它将显示整个栏。

为什么是这样?

我知道有一个内置的加载栏,但这只是我遇到的问题的一个例子。

4

1 回答 1

2

我建议您开始阅读有关线程、后台工作人员、调度程序的内容。除非您在解决方案中添加线程,否则整个应用程序都在 UI 线程的帮助下运行。

如果您有可以串行执行的任务,则无需实现线程或后台工作人员。在您的情况下,您正在尝试执行 2 个任务。

  1. 更新矩形并将其绘制在窗口上
  2. 休眠线程 50 毫秒

当 UI 线程执行 thread.Sleep(50); 它无法绘制(以矩形显示进度)。这就是您的应用程序会冻结几秒钟并在您看到任何进展之前完成的原因。我将尝试用 2 个示例来解释这一点。

示例:1为您的演示应用程序 添加一个带有IsIndeterminate="True"和的进度条。Button1

<ProgressBar IsIndeterminate="True"  Height="20" Name="progressBar1" Width="177" Visibility="Hidden" />

在后面的代码中,

 private void button1_Click(object sender, RoutedEventArgs e)
        {
            progressBar1.Visibility = Visibility.Visible;
            Thread.Sleep(5000);
            progressBar1.Visibility = Visibility.Hidden;
        }

如果您运行此代码,您将看不到任何进度条,因为代码正在串行执行。为确保进度条正确显示和隐藏,请执行以下更改。

示例 2:

private void button1_Click(object sender, RoutedEventArgs e)
        {
            progressBar1.Visibility = Visibility.Visible;
            Thread t = new Thread(DoMyWork);
            t.Start();
        }

   private void DoMyWork()
                {
                    Thread.Sleep(5000);
                    //hide the progress bar after completing your work
                    this.Dispatcher.Invoke((Action)delegate { progressBar1.Visibility = Visibility.Hidden; });
                }

在此处输入图像描述

运行此代码,您可以看到当 UI 线程更新进度条时,新创建的线程执行DoMyWork函数。

您将需要this.Dispatcher.Invoke((Action)delegate在 UI 线程中创建 progressBar1 并且您不能在另一个线程中访问它。即线程 t = 新线程(..)

PS-这是一种肮脏的编码方式。这只是为了说明在 OP 的情况下应该如何工作。

于 2013-10-13T15:01:20.957 回答