This project has moved. For the latest updates, please go here.
6

Closed

RaisePorpertyChanged() fails in ReleaseBuild

description

Hi,
This method fails in Release build due to performance optimizations. Here is an article that documents the issue. I am using BL00014.

http://mvvmlight.codeplex.com/workitem/list/basic?field=CreationDate&direction=Descending&issuesToDisplay=Open&keywords=Release&emailSubscribedItemsOnly=false

Thanks for a great product
Craig Richards
Closed Oct 13, 2014 at 12:54 PM by lbugnion

comments

danthman wrote Apr 22, 2011 at 2:38 AM

I ran into this bug today as well. What's interesting is that it only occurs when running a release build directly from the executable (i.e., not from within Visual Studio). With Debug builds, you can run the executable or from within Visual Studio, and it works fine. The problem occurs when setting a property with RaiseProperyChanged(). A workaround for now is to just use RaisePropertyChanged(() => NameOfProperty) instead.

Here's the error I received when debugging in Visual Studio:

System.InvalidOperationException was unhandled
Message=This method can only by invoked within a property setter.
Source=GalaSoft.MvvmLight.WPF4
StackTrace:
   at GalaSoft.MvvmLight.NotifyPropertyChanged.RaisePropertyChanged() in C:\Desktop\mvvmlight-cd110ba734ea\mvvmlight_cd110ba734ea\GalaSoft.MvvmLight\GalaSoft.MvvmLight (NET35)\NotifyPropertyChanged.cs:line 126
   at MyProj.ViewModels.NavigationPanelViewModel.Update(Int32 periodOffset) in C:\Documents\Projects\MyProj\Designs\Main\Solution\MyProj\ViewModels\NavigationPanelViewModel.cs:line 48
And here's the class file in question:
public class NavigationPanelViewModel : ViewModelBase
{
    private int _scenarioPeriod = 0;
    private readonly int _maxScenarioPeriod;

    public ICommand JumpStartCommand { get; set; }
    public ICommand StepBackwardCommand { get; set; }
    public ICommand StepForwardCommand { get; set; }

    public int ScenarioPeriod
    {
        get { return _scenarioPeriod; }
        set
        {
            if (value == _scenarioPeriod) return;
            _scenarioPeriod = value;
            RaisePropertyChanged(); // *******this is the offending line of code*******
        }
    }

    public int MaxScenarioPeriod
    {
        get { return _maxScenarioPeriod; }
    }

    public NavigationPanelViewModel(MainDbContextLocator dbContextLocator)
    {
        _maxScenarioPeriod = dbContextLocator.Current.Contacts.Max(c => c.ScenarioPeriod);
        JumpStartCommand = new RelayCommand(() => Update(-ScenarioPeriod + 1));
        StepBackwardCommand = new RelayCommand(() => Update(-1));
        StepForwardCommand = new RelayCommand(() => Update(1));
    }

    public void Update(int periodOffset)
    {
        var scenarioPeriod = Math.Min(MaxScenarioPeriod, Math.Max(1, ScenarioPeriod + periodOffset));
        if (scenarioPeriod == ScenarioPeriod) return;
        ScenarioPeriod = scenarioPeriod; // ******* this is line 48 *******
        App.Messenger.Send<int>(scenarioPeriod, MessageToken.ScenarioPeriodChanged);
    }
}

danthman wrote Apr 22, 2011 at 2:40 AM

@Craig Richards: You seem to have pasted the wrong link.

duluca wrote May 19, 2011 at 2:49 PM

I'd recommend increasing the impact of this item from low to high.

CtrlAltDel wrote Jul 21, 2011 at 3:01 AM

I have the same problem too (http://stackoverflow.com/questions/6770809/mvvmlight-raisepropertychanged-error-in-release-builds). I'm guessing there's some weird compiler optimisation which is interfering with the way that ObservableObject.RaisePropertyChanged() reads the StackTrace to check whether the method is being called from inside a property setter, as the stack trace doesn't include the call to RPC from within the setter.

Very strange that it works from within Visual Studio but not when run from Explorer - maybe the .vshost.exe is doing something?

Obalix wrote Jul 21, 2011 at 9:00 PM

duluca wrote Jul 21, 2011 at 9:31 PM

@Obalix That's a work around at best not much of a solution. The only reason for using this feature is the convenience of not having to type something in between the PropertyChanged parans.

CtrlAltDel wrote Jul 21, 2011 at 11:00 PM

Some nice circular linking between myself and Obalix - he links to my StackOverflow question, in which I link back to this issue :-). I agree with duluca, this is definitely an issue that needs resolving, so please vote it up so that Laurent knows we consider it important!

Aurimas86 has already suggested a better approach, using expressions rather than a stack trace (http://mvvmlight.codeplex.com/discussions/243955). It has the double benefit of removing some more boilerplate code, so IMHO it would be a double benefit to have this fixed.

Obalix wrote Jul 22, 2011 at 4:33 AM

Tweetet with Laurent about it here is his answer: http://twitter.com/LBugnion/status/94173507906318337

lbugnion wrote Jul 22, 2011 at 5:04 AM

Outstanding work guys. I have been watching this indeed and will do my best to fix it in the next release.

cheers
Laurent

lbugnion wrote Sep 11, 2011 at 10:11 PM

Fixed in V4 beta 1

lbugnion wrote Sep 11, 2011 at 10:11 PM

Should be a bit more explicit. I removed this method from V4 beta 1 due to the flaws. Instead I implemented the Set() method as proposed here (with a few changes). Blog post will follow.