AddNew performance question

AddNew performance question

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


bartol posted on Tuesday, January 18, 2011

Hi,

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() 
{
    Add(MyResult.New());
    return Items[Items.Count - 1];
}

The code that fills the collection is something like this:

foreach(var item in CalculationResults)
{
    var c = AddNew();
    c.Value = item.value;
    c.ReferenceId = item.Id;
}

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,
B

JonnyBee replied on Tuesday, January 18, 2011

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.

 

bartol replied on Tuesday, January 18, 2011

Hi,

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...).

Thanks,

Marjon1 replied on Tuesday, January 18, 2011

Since you've already checked RaiseListChangedEvents, I make the following two suggestions.

 

 

 

bartol replied on Wednesday, January 19, 2011

Hi,

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.

Cheers,

RockfordLhotka replied on Wednesday, January 19, 2011

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?

bartol replied on Thursday, January 20, 2011

Hi,

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).

B

RockfordLhotka replied on Thursday, January 20, 2011

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