Sandeep Bansal
Sandeep Bansal

Reputation: 6394

Progress Bar Binding isn't updating from a thread

I'm trying to run a look to update CPU Usage onto a progress bar from a thread.

The code I have here is:

    private static int _cpuUsage;
    protected PerformanceCounter cpuCounter;
    private Thread thread;

public CPUUsageIndModel()
    {
    cpuCounter = new PerformanceCounter
                     {CategoryName = "Processor", CounterName = "% Processor Time", InstanceName = "_Total"};
    thread = new Thread(GetCurrentCpuUsage);
    thread.Start();
    }

public void GetCurrentCpuUsage()
{
    while (true)
    {
        _cpuUsage = Convert.ToInt32(Math.Round(cpuCounter.NextValue()));
        Thread.Sleep(1000);
    }
} 

public int GetCPUUsage
{
    get { return _cpuUsage; }
    set
    {
        _cpuUsage = value;
        NotifyPropertyChanged("_cpuUsage");
    }
}

Now the thing is I've tried starting the thread with just:

public void GetCurrentCpuUsage()
{
   _cpuUsage = 40;
}

And it works fine, so that leaves the cpuCounter and loop used.

Can anyone point out any mistake that I may have made.

Thanks

EDIT - Complete Class and some minor tweaks:

public class CPUUsageIndModel : INotifyPropertyChanged
    {
        public static int _cpuUsage;
        protected PerformanceCounter cpuCounter;
        private Thread thread;

        public CPUUsageIndModel()
        {
            cpuCounter = new PerformanceCounter
                             {CategoryName = "Processor", CounterName = "% Processor Time", InstanceName = "_Total"};
            thread = new Thread(GetCurrentCpuUsage);
            thread.Start();
        }

        public void GetCurrentCpuUsage()
        {
            while (true)
            {
                CPUUsage = Convert.ToInt32(Math.Round(cpuCounter.NextValue()));
                Thread.Sleep(1000);
            }
        } 

        public int CPUUsage
        {
            get { return _cpuUsage; }
            set
            {
                _cpuUsage = value;
                NotifyPropertyChanged("_cpuUsage");
            }
        }


        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion
    }

Upvotes: 0

Views: 1230

Answers (2)

LadderLogic
LadderLogic

Reputation: 1140

Looks like you got it almost right, at least looking from the edit. Only, you are raising the property changed on a field name instead of the property name. Here is the fix:

public int CPUUsage
        {
            get { return _cpuUsage; }
            set
            {
                _cpuUsage = value;
                NotifyPropertyChanged("CPUUsage"); // Notify CPUUsage not _cpuUsage
            }
        }

and your binding should look like {Binding Path=CPUUsage}

Upvotes: 1

Nikola Radosavljević
Nikola Radosavljević

Reputation: 6911

You need to notify WPF runtime of the change. For that purpose you implement INotifyPropertyChanged interface.

You seem to attempt that here, but you're not doing it the right way (you didn't display all of relevant code but I fairly sure your implementation is not correct).

You need to: 1. Bind to a public property (we don't see this in code you pasted) 2. Send notification from setter of the property, if value is changed 3. Change the value through property setter

You may be doing point one correctly, we don't see this, but you are notifying that private field changed, and you should notify that property changed (NotifyPropertyChanged("GetCPUUsage")). You are also setting the value by directly accessing field (_cpuUsage = 40;), and you should do it through setter (GetCPUUsage = 40;).

In this context your property name is a bit strange. I'd rename GetCPUUsage to CPUUsage, as you can get and set it's value. Also prefix Get should be used for methods, not properties.

Upvotes: 1

Related Questions