Search code examples
c#postsharp

RaisePropertyChanged on Porperty updated in another thread is not called


Let's say I have this class with the RaiseProperyChanged attribute from PostSharp:

[NotifyPropertyChanged]
public class MainViewModel
{
    public int RandInt { get; set; }

    public MainViewModel()
    {
        RandInt = 10;
        new Task(TaskStart).Start();
    }

    private void TaskStart()
    {
        Random rand = new Random();
        while (true)
        {
            RandInt = rand.Next(9999);
        }
    }
}

Binding RandInt to a label or other control wil result in no change of the label. This means that the value of the label will be 10 all the time because the property is changed from another thread. How to handle this strange behaviour? Doing this with MVVM Light with RaisePropertyChanged() in the setter of the property works fine.


Solution

  • This is a design consequence of PostSharp. The problem is that the method TaskStartinstrumented by the aspect [NotifyPropertyChanged] flushes the event queue in the end, but this method does not ever end.

    This will be addressed in a future version of PostSharp. In the meanwhile, you can use method NotifyPropertyChangedServices.RaiseEventsImmediate(). See the example:

    [NotifyPropertyChanged]
    public class MainViewModel
    {
        public int RandInt { get; set; }
    
        public MainViewModel()
        {
            RandInt = 10;
            new Task(TaskStart).Start();
        }
    
        private void TaskStart()
        {
            Random rand = new Random();
            while (true)
            {
                AsyncRandomNumber = random.Next( 9999 );
    
                // Raise the events now, because the method TaskStart never ends.
                NotifyPropertyChangedServices.RaiseEventsImmediate( this );
            }
        }
    }