LoadProperty vs SetProperty setters and performance

LoadProperty vs SetProperty setters and performance

Old forum URL: forums.lhotka.net/forums/t/12232.aspx


Tatjana posted on Wednesday, November 20, 2013

Hi there,

In my windows project I have more than 50 registered properties per object (more or less) and not every one of them has corresponded field in a Database.

If I use SetProperty as a setter, I run to a severe performance issues, due to PropertyHasChanged event being fired all the time a property changes its value.

Now, when I use LoadProperty as a setter to all properties that I do not want PropertyHasChanges to be fired, and leave SetProperty setter for ones that I do like this event to be fired, the performance is awesome (as it should be), BUT now, all properties that I need to save in the database that used LoadPropery setter are not marked as Dirty, and because of that they cannot be saved (I only save Dirty properties in my database; insert/update).

How can I use LoadProperty, but make the property dirty in the same time (I want the property to be dirty, but I do not want rules to be checked against them automatically or fire OnChildChanged event)? Or would you suggest another approach?

I use CSLA.NET 4, .net 4 framework, and winforms.

 

Thanks in advance,

Tanja.

ajj3085 replied on Wednesday, November 20, 2013

Is the performance an issue when loading from the database or while the user is editing the properties on the screen? 

If its during the database fetch you can use BypassPropertyChecks in a using block and set all your properties there; that will temporarily disable the problematic events.

If its on user editing do you have the controls set to update the data source OnPropertyChanged or OnValidation?  The former will fire property changed for each keystoke, while the latter will only fire when the user tabs out of the control.  You may need to switch to OnValidation if your rules are complex enough that its causing an issue.  Also make sure you set the PropertyChangedMode on the ApplicationContext on startup of your app; it defaults to Xaml which may have an impact. I've had pretty complex forms using OnPropertyChanged for most controls and performance was good, but this was a few years ago.

Tatjana replied on Wednesday, November 20, 2013

- Yes, PropertyChangedMode  is set to ApplicationContext.PropertyChangedModes.Windows

- I override PropertyHasChanged and OnChildChanged.

- The performance issues are when user edits the controls.  I also use BypassPropertyCheckes, but the properties that are set in that block are not mark as dirty either, which makes sense, but I do need them dirty).

I guess what I want to achieve is this:

- property A of business object child, to be set (all rules run etc., which is achieved with the SewtProperty setter, and that's good).  This will fire the child's PropertyHasChanged and parent's PropertyHasChanged  and parent's OnChildChange events

- In the child's PropertyHasChanged I set new value for property B, which I want to be marked as dirty, but I do not want this change to fire the child's PropertyHasChanged and parent's PropertyHasChanged  and parent's OnChildChange events. I want to be able to save this property B in the DB

Can this be achieved?

I haven't tried to override OnValidation yet though.

JonnyBee replied on Wednesday, November 20, 2013

Hi,

The recommended way of updating other properties is to use BusinessRules. CSLA .NET 4 is quite vague - which version do you use? 

Do you use sync rules that hit a database? 

I would recommend that you use a profiler and check where the time is consumed in your application.

IIRC starting from CSLA 4.3 and up you have a new LoadPropertyMarkDirty which is also used when you update other properties in a BusinessRule (context.AddOutValue). This method will load the value and mark the field as dirty if the value was changed. 

Tatjana replied on Wednesday, November 20, 2013

I use CSLA.NET 4.1.0

I use a sync rule that hits a database, yes, and I tried to make it async, but I ran into an issue to have the Save button disabled cause the object was still in Busy state. 

I like this LoadPropertyMarkDirty that you mentioned; looks like it does exactly what I like to achieve. Can it also be used as a property setter?  

Do you recommend I upgrade to this version?  How much would the upgrade cost?

JonnyBee replied on Wednesday, November 20, 2013

I'm not so happy on using LoadPropertyMarkDirty in the setter. 

As you already mentioned - you are overriding PropertyHasChanged and it is actually base.PropertyHasChanged() that trigger the rule engine and raise OnPropertyChanged event(s). 

So for those properties that should _NOT_ call the rule engine or raise OnPropertyChanged - you could just have f.ex a static list of these properties and add a check in PropertyHasChanged to just return and do nothing if the propertyinfo is in this list.

I DO recommend to keep the same coding style for all your  properties. You _could_ also create your own interface and subclass of PropertyInfo and check for an additional flag in PropertyHasChanged. 

My recommendation is to use SetProperty/GetProperty in you property declarations such that you can also have authorization on your properties. So if you have overrides for CanReadProperty/CanWriteProperty that does database access this may also be a cause for sluggish performance. 

The upgrade from 4.1 to 4.3 should be fairly easy. I do not believe there is many breaking changes. You should however read the release notes to get an overview of the changes. 

Tatjana replied on Wednesday, November 20, 2013

I'd like to try this OnValidation (or OnValidationComplete, since I do not see this OnValidation event) approach instead of OnPropertyChanged.  Could you recommend any sample project that's available for download that I can take a look at?

JonnyBee
So for those properties that should _NOT_ call the rule engine or raise OnPropertyChanged - you could just have f.ex a static list of these properties and add a check in PropertyHasChanged to just return and do nothing if the propertyinfo is in this list.

What do you mean by "f.ex"? 

 

ajj3085 replied on Wednesday, November 20, 2013

Tatjana
I'd like to try this OnValidation (or OnValidationComplete, since I do not see this OnValidation event) approach instead of OnPropertyChanged.  Could you recommend any sample project that's available for download that I can take a look at?

Sorry I wasn't clear.  I don't mean you need to override anything, I mean change the designer properties on the Form controls itself, the Data Source Update Mode.  See this Figure 1 & 2 in this MSDN link:  http://msdn.microsoft.com/en-us/library/aa480734.aspx

Tatjana replied on Thursday, November 21, 2013

Ah, I see.  Thanks for the link, I am checking that too at the moment.

~Tanja

JonnyBee replied on Thursday, November 21, 2013

"f.ex" is abbreviation for "for example". 

The difference between LoadProperty and SetProperty is that SetProperty calls:

 

The mistake that many developer make is to add additional code in the property setter. When users "tab" around in the form the DataBinding wil actually call the property setters - but SetProperty will only act on those that have a new value. 

If your performance is sluggish, I would first suspect that you have code in 

that degrades the performance as the user tabs around.

Could you show us how your properties is defined? 

Tatjana replied on Thursday, November 21, 2013

Hi Jonny,

Thank you for your quick responses. My setters are simple, using SetProperty.  Something like shown in the attached file [PseudoCode.zip; 4K]

 

~Tanja

Copyright (c) Marimer LLC