I am using CSLA 4.0 and WPF and I have this BO that has a child collection (based on BusinessListBase) where the results of a calculation are stored. The child that is stored in the collection only has two properties: a Guid and a double.
The problem I have is when I use AddNew to create over 10,000 items (the results of my calculation) it takes a long time to create them. I am overriding AddNewCore as such:
protected override MyResult AddNewCore()
return Items[Items.Count - 1];
The code that fills the collection is something like this:
foreach(var item in CalculationResults) I wonder if there is a better and faster way to do this? I stepped through the CSLA code and there are lot of IsValid checks during the process which maybe could be postponed until the end of my bulk operation. Thanks,
var c = AddNew();
c.Value = item.value;
c.ReferenceId = item.Id;
foreach(var item in CalculationResults)
I wonder if there is a better and faster way to do this? I stepped through the CSLA code and there are lot of IsValid checks during the process which maybe could be postponed until the end of my bulk operation.
If you are loading that amount of data then you should make sure to set:
RaiseListChangedEvents = false;
before you add items and
RaiseListChangedEvents = true;
when you are done.
I presume this is done in your data access layer and not with active databinding?
Anyway - the ListChangedEvents may have serious affect of performance and should be off while you load data.
I have tried adding the RaiseListChangedEvents but it does not make a measurable difference since I am not subscribing to any event in this specific case. I am wondering if I should do a fetch on the list and load it through the DataPortal and resetting it but I am afraid that is going to cause havoc with the parent/child relationships of the objects.
The only way I managed to speedup the additions to nearly instant was by hacking the CSLA code by setting a static flag which returns true for IsValid in BusinessBase (terrible I know...).
Since you've already checked RaiseListChangedEvents, I make the following two suggestions.
Thanks for that. I just tried BypassPropertyChecks now but still no difference. Also the problem appears in all types of list manipulation, for example, calling MyList.Clear() where MyList contains 1000 items similar to what I described above takes a couple of seconds to process unless I "suspend" the IsValid processing on BusinessBase. Very odd.
What do you mean by "IsValid checks"?
The IsValid implementation in BusinessBase is passive. In other words it doesn't run unless some code reads the property value. That implies that somewhere in the application there's some code that's re-reading IsValid as each child is added? What is that code?
The IsValid checks are triggered by a PropertyStatus in the UI. I can email you a stack trace if you want but basically what happens is that the AddNewCore indirectly triggers a Child_PropertyChanged which later on causes a ObjectStatus.Refresh() which calls IsSavable thus IsValid is called. The code I posted above does not show this because I only found it later. This exact same things happens when I call Clear in the collection. In this particular screen a call to Clear of a collection with 8 items causes over 50 calls to IsValid (that is as fas as I counted).
In this case you might try unbinding the object from the UI before doing mass operations.
I think someone already suggested setting RLCE to false? Unfortunately the .NET ObservableCollection base class doesn't have that concept, so there's no way to entirely disable collection changed events, and that's what most UI components use to know they should refresh...
Copyright (c) Marimer LLC