Question

If you can picture this as a loading bar:

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

So, the application will not show the progress of adding additional rectangles. Instead it just freezes up for the total time of the thread sleep and when the for loop is finished it will show the entire bar.

Why is this?

I'm aware there is a loading bar built in, but this is just an example of problems I have been having.

Was it helpful?

Solution

I'd recommend you start reading about Threads, background workers, dispatchers. Unless you add threads to your solution, the entire applications runs with the help of UI thread.

If you have got task which can be performed serially, you need not implement Threads or background worker. In your case, you are trying to do 2 task.

  1. Update the rectangle and draw it on window
  2. Sleep thread for 50 milliseconds

When UI thread executes thread.Sleep(50); it cannot draw (show progress in rectangle). That's the reason your application kind of freezes for seconds and gets completed before you could see any progress. I am going to try and explain this with 2 examples.

Example:1 Add a progress bar with IsIndeterminate="True" and Button1 to your demo application.

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

In code behind,

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

If you run this code, You will not see any progress bar as the code is getting executed serially. To make sure that progressbar is getting shown and hide properly, do following changes.

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

enter image description here

Run this code and you can see that while UI thread updates progressbar, new thread created executes DoMyWork function.

You will need this.Dispatcher.Invoke((Action)delegate as progressBar1 was created in UI thread and you cannot access it in a another thread. i.e.Thread t = new Thread(..)

P.S.- This is dirty of way to coding. It is just to give an idea that how things should work in OP's case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top