-1

I'm trying to get at progress bar to update based on how many times a loop have been executed. The loop is running in it's own thread. I'm under the impression that Dispatcher.BeginInvoke is a good choice and implemented it. I've also read that the dispatcher is able to update the GUI even though it's running its own thread. However, I'm not able to get this to work when trying to notify the binding about an update, implementing INotifyPropertyChanged. I've seen some blogs, questions etc that suggest different magic methods to solve this, but since I've read this should be handled by the dispatcher I would like to avoid that.

NB! This is not an Observable collection, which I've read is not handled by the dispatcher.

Sample code from viewmodel

Application.Current.Dispatcher.BeginInvoke(() =>
{
    this.Progress = 0;
    for (int i = 0; i < this.nrOfLoops; i++)
    {
        // implementation goes here ...
        if (i % 100 == 0) // Only update every 100 cycle 
        {
             this.Progress = (double)i / nrOfLoops * 100;
             this.NotifyPropertyChanged("Progress");
        }
    }
}, DispatcherPriority.Background);

XAML

<ProgressBar Value="{Binding Path=Progress}"/>

The GUI is not continuously updated, only filled to 100% when all is done. I've tried messing around with DispatcherPriority just in case, but without results. I do know that the binding is ok from setting it to a default value, as well as the fact that the progress bar is filled when finished.

So... What am I doing wrong here? Or have I been misinformed about the dispatcher being able to handle this? It feels like this must be a very common scenario.

Anders
  • 499
  • 1
  • 5
  • 18

1 Answers1

1

You can use the generic implementation of Invoke and let another method which returns "Task" take the responsibilty of the management of your progress bar.

Application.Current.Dispatcher.Invoke<Task>(UpdateBar, DispatcherPriority.Background);

and this is the method:

private Task UpdateBar()
    {
        return Task.Factory.StartNew(() =>
        {
            this.Progress = 0;
            for (int i = 0; i < 100; i++)
            {
                this.Progress = (double)i;
                this.NotifyPropertyChanged("Progress");
                Thread.Sleep(30);
            }
        });
    }
aminexplo
  • 360
  • 1
  • 13
  • Thank you aminexplo, I will try this when I'm back home from work. – Anders Feb 15 '16 at 06:43
  • Unfortunately this doesn't work for me. It will not recognize Invoke as a generic method. I'm using Community 2015 edition. Don't know if that matter in any way? I'm using System.Windows just as MSDN says. – Anders Feb 15 '16 at 14:40
  • This is now working! The target Framework was set to 4.0, but I changed it to 4.5 and in there Invoke existed. Thank you for your help. – Anders Feb 15 '16 at 16:55
  • @Anders glad to hear that. YW. – aminexplo Feb 15 '16 at 18:33