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

Problem with RaisePropertyChanged() in Release Mode

Mar 31, 2011 at 10:44 AM
Edited Mar 31, 2011 at 10:46 AM

Hi community,

one of the RaisePropertyChanged() implementations in the BaseNotify class - the parameterless one to be precise - is marked in the sources with the warning

/// <remarks>
///     May not work on some systems (64-bit, for example, not yet supported by Silverlight). 
/// </remarks>

but apparently the stack based approach for determining a property name is even more fragile than this.

As has been discussed elsewhere (see Emiel Jongerius' analysis in INotifyPropertyChanged implementations: An Overview) I just ran into the problem that the stack frame based implementation fails in a Silverlight application running in optimized Release mode even on standard 32bit Windows. It's kind of hard to reproduce the error on a developer machine, but installing the deployment package on a remote WebServer is sure to throw an exception ("NotifyPropertyChanged() can only by invoked within a property setter.").

The tagging of RaisePropertyChanged() with a

  [MethodImpl(MethodImplOptions.NoInlining)]

Attribute as implemented in BaseNotify is obviously not enough to make this work. Come to think of it, this is actually not surprising because the stack trace gets mangled when the containing property setter method gets inlined in the first place.

So my question is this: Is there any way other than tagging every property setter with [MethodImpl(MethodImplOptions.NoInlining)] (as suggested in INotifyPropertyChanged implementations: An Overview) to make the parameterless RaisePropertyChanged() work in optimized Release mode? Is marking each property setter even enough to make the stack based approach work reliably, or should the stack-tracing approach rather be removed from BaseNotify entirely?

Thanks for any advice
DrJ

Coordinator
Mar 31, 2011 at 11:23 AM

From everything I've discerened this has officially become a Bad Idea (tm) and should be removed from the product - I'll work on that.

I've been mulling the idea of incorporating this. I like that it's faster but I also think property changed is one of those that is tied to UI/user experience so not sure if the cases that compare 500,000 iterations really matter in the real world. It's also a quirky convention, but so is (()=>PropertyName). What are everyone's thoughts around this idea:

http://zamboch.blogspot.com/2011/03/raising-property-changed-fast-and-safe.html

Mar 31, 2011 at 11:49 AM
Edited Mar 31, 2011 at 12:13 PM
jeremylikness wrote:

From everything I've discerened this has officially become a Bad Idea (tm) and should be removed from the product - I'll work on that.

After some more reading up I couldn't agree more.

I've been mulling the idea of incorporating this. I like that it's faster but I also think property changed is one of those that is tied to UI/user experience so not sure if the cases that compare 500,000 iterations really matter in the real world. It's also a quirky convention, but so is (()=>PropertyName). What are everyone's thoughts around this idea:

http://zamboch.blogspot.com/2011/03/raising-property-changed-fast-and-safe.html

Well, that syntax ranks among the quirkiest I've come across so far. Maybe you could include both ways in BaseNotify - then each developer can choose if he/she wants it slow and clean or quirky and fast :-).

Getting serious again: have you ever considered looking at MSIL weaving - that's one of the options mentioned in Emiel's essay?
The biggest drawback would certainly be the introduction of a dependency on an MSIL weaving framework - on the other had this could be the way to go if you want

[NotifyPropertyChanged]
public string MyProperty { get; set; }

Then, again, it might not be possible to cover a mechanism as pervasive als MSIL weaving through a framework assembly like Jounce when it would have to be activated for the entire Silverlight solution. Oh well ...

Oh, and by the way - DataBinding and INPC are a very versatile mechanism that can be used for controlling many more aspects of a GUI than just the data displayed. I even have a valid example for a data bound visibility property (normally it would be better to use Visual States for this, but in this case the set of target items is variable, which defeats the VSM approach). What I mean to say is that you shouldn't discount the effect of an efficient INPC implementation on overall GUI performance.