0

I have my window with a progress bar in it.

So in my "Do" Method, I want to change a status text and my progress bar without blocking the UI:

public void Do()
{
   ProgressBar.Value = 0;
   StateLabel.Content = "Start..."

   // Do Things   

   ProgressBar.Value = 50;
   StateLabel.Content = "Running part 2"

   // Do things

   ProgressBar.Value = 100;
   StateLabel.Content = "Finished. Closing progress window..."

   Thread.Sleep(1000);
   this.Close();
}
PassionateDeveloper
  • 14,558
  • 34
  • 107
  • 176

2 Answers2

1

Just in addition to the comments here should be a working snippet for your challenge:

    private void MainWindowButton_OnClick(object sender, RoutedEventArgs e)
    {
        ((MainWindowViewModel)this.DataContext).ButtonClickEvent();
        Application.Current.Dispatcher.Invoke(Do);
    }

    public async Task Do()
    {


        myLabel.Content = "Start...";

        // Do Things   
        await Task.Delay(1000);
        myLabel.Content = "Running part 2";

        // Do things
        await Task.Delay(1000);
        myLabel.Content = "Finished.";
    }

To learn more about to go around freezes in WPF I found this question quite instructive.

Patrick
  • 387
  • 3
  • 15
1

The key point here is that you cannot both "do things" that blocks and update a ProgressBar on the same thread simultaneously.

You should display the progress bar on the UI thread, start a task that performs the long-running work on a background thread and then hide the progress bar once that task has finished:

public async Task Do()
{
    ProgressBar.Value = 0;
    StateLabel.Content = "Start...";

    await Task.Run(() =>
    {
        // Do things ...
        Thread.Sleep(1000);
    });

    ProgressBar.Value = 50;
    StateLabel.Content = "Running part 2";

    await Task.Run(() =>
    {
        // Do things ...
        Thread.Sleep(1000);
    });

    ProgressBar.Value = 100;
    StateLabel.Content = "Finished. Closing progress window...";

    this.Close();
}
mm8
  • 163,881
  • 10
  • 57
  • 88