RunRules generate "Collection was modified; enumeration operation may not execute."

RunRules generate "Collection was modified; enumeration operation may not execute."

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


mosgath posted on Thursday, December 20, 2012

I have a Silverlight 4.0 Client calling a method that executes a command object.  The DataPortal_Execute of the Command object on the server calls a class that takes a formatted text file and parses it into multiple lines (business objects) that include 1 material business object each and then returns the set of lines.  This works great for a single request.  However, occasionally when multiple clients call this command on the server during the same time, individual material objects will have a rule result indicating an exception in the running the rules or the method parsing the file will generate a similar message.  After the material is set and all options (children of material) are loaded from the file for that material, I revalidate the model number on materials (see code below) so the selected options can be included with the validation.  During this, I get one of two errors below.  In production, I am using CSLA 4.2, but I have tried upgrading to CSLA 4.3.13 locally.  The issue still exists.  

Is there a way from me to invoke the RunRules on the Server and be thread-safe?  

//Summary of File Helper called by Command

while(!FileEndOfStream)

{

   _newLine = Line.New(order);

   _newLine.Material.ModelNumber = _value;

   //populate other line fields

  //populate options

  _newLine.Material.CheckRules(Model.Material.ModelNumberProperty);

}

//From Material Model Object

        internal void CheckRules(Csla.Core.IPropertyInfo prop)

        {

 

            if (Csla.ApplicationContext.LocalContext.Contains("Loading Order")) return;

            var _propertyNames = this.BusinessRules.CheckRules(prop);

            foreach (var _property in _propertyNames)

            {

                OnPropertyChanged(_property);

            }

        }

 

Errors:

Property load or set failed for property ModelNumber (Collection was modified; enumeration operation may not execute.)

at Csla.Core.BusinessBase.SetProperty[P](PropertyInfo`1 propertyInfo, P newValue, NoAccessBehavior noAccess)     

at Csla.Core.BusinessBase.SetProperty[P](PropertyInfo`1 propertyInfo, P newValue)     

at Model.Material.set_ModelNumber(String value) in ..\Data Models\Model.Server\Material.generated.cs:

at Model.Helpers.FileHelper.UploadFile(Byte[] contents, Order& order, Int32 lineNumber) in ..\Data Models\Model.Server\Helpers\FileHelper.cs:

at Model.Commands.Command.DataPortal_Execute() in ..\Data Models\Model.Server\Commands\Server.Command.cs:

 

Collection was modified; enumeration operation may not execute.

    at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)     

at System.Collections.Generic.List`1.Enumerator.MoveNextRare()     

at System.Collections.Generic.List`1.Enumerator.MoveNext()     

at Csla.Rules.BusinessRules.<>c__DisplayClass2f.<RunRules>b__24(RuleContext r)     

at Csla.Rules.RuleContext.Complete()     

at Csla.Rules.BusinessRules.RunRules(IEnumerable`1 rules, Boolean cascade, RuleContextModes executionContext)     

at Csla.Rules.BusinessRules.CheckRulesForProperty(IPropertyInfo property, Boolean cascade, RuleContextModes executionContext)     

at Csla.Rules.BusinessRules.CheckRules(IPropertyInfo property, RuleContextModes executionContext)     

at Csla.Rules.BusinessRules.CheckRules(IPropertyInfo property)     

at Model.Material.CheckRules(IPropertyInfo prop) in ..\Data Models\Model.Server\Material.cs     

at Model.Helpers.FileHelper.UploadFile(Byte[] contents, Order& order, Int32 lineNumber) in ..\Data Models\Model.Server\Helpers\FileHelper.cs:

at Model.Commands.Command.DataPortal_Execute() in ..\Data Models\Model.Server\Commands\Server.Command.cs:

JonnyBee replied on Friday, December 21, 2012

Do these exceptions occur after the ApplicationPool has been recycled?

We have fixed a thread race condition on initialization of BusinessRules (calling AddBusinessRules) but still have a known thread race issue for initialization of static AuthorizationRules (callingAddObjectAuthorizationRules) for both Csla 4.3 and 4.5 .

http://www.lhotka.net/cslabugs/edit_bug.aspx?id=1107 
http://www.lhotka.net/cslabugs/edit_bug.aspx?id=1078

These fixes is in Trunk but not yet released in Csla 4.3 (AFAIK) so you might download the Csla 4.3 source and rebuild yourself and check/verify if this solved your issue.

mosgath replied on Friday, December 21, 2012

Unfortunately, that doesn't appear to fix the issue.  I still get the same messages.  I redesigned how this worked.  The Rule on Material was calling a command to retrieving data from our ERP system, applying updates to the data including a validation message code field, and setting a validation message for the rule.  I removed this rule and setup a new one to only trigger from a validation code field.  The file parser now calls the command to retrieve the data the rule was used for.  The new rule triggers when the command is setting the values.  This new rule has a simple case statement to translate the code into our validation message.  Now I just have to change the other places in the application to do this explicitly instead of relying on the rule.  It actually sets me up for some other future performance tuning we were considering.

 

 

Copyright (c) Marimer LLC