How to track down when a collection is modified

Posts   
 
    
jshallard
User
Posts: 62
Joined: 23-Mar-2005
# Posted on: 23-Oct-2007 00:30:10   

Version: 2.5 Templates: Adapter

If anyone has any advice on how to debug the following problem , it would be much appreciated:

When iterating through an entity collection using a foreach loop I get the following error:

**“Collection was modified; enumeration operation may not execute”**

So, i know that this is a .Net error that occurs when the collection that is being iterated is modified… however I am having a hard time pinning down exactly which bit of code it is that modifies the collection – especially as the change almost certainly occurs out of the context of the loop (and as such I can’t just add a “watch” an see when the collection changes).

There is no code directly within the loop that makes any modifications – however, there are several methods called from within the loop that go off and do other things – including queries. I think that somehow the background LLBLGen code that deals with allowing reuse of collections is connected to my problem, and that a collection that is used elsewhere is changing the collection in my foreach loop… I have spent several hours stepping through a lot of code, and not managed to pin it down. I never really fully understood the concept of “Context” within LLBLGen, but i think that may be also connected to the problem (or the solution)!

  • Is there a way to peek inside the LLBL Context and see what collections are cached/linked and when they change?
  • Is there something else I am missing?

Thanks for any help

DvK
User
Posts: 318
Joined: 22-Mar-2006
# Posted on: 23-Oct-2007 00:36:27   

Are you deleting something from the collection while in the for-each loop ?

jshallard
User
Posts: 62
Joined: 23-Mar-2005
# Posted on: 23-Oct-2007 02:04:47   

No. The loop itself is actually very simple:

public static decimal GetMinimumCost(ShopEntity shop)
{
    decimal minPrice = decimal.MaxValue;

    foreach (ProductEntity entity in shop.Products)
    {
        if (entity.PriceContainer.MinCost < minPrice)
        {
              minPrice = entity.PriceContainer.MinCost;
        }   
    }
    
    return minPrice;
}

however the property "PriceContainer" is a lazy loading property, which goes off and does a fair amount of processing (and some queries) in order to get all the price information. It is somewhere in here that the productCollection is altered.

Any ideas / debug techniques on how to track down exactly where the collection is altered would be much appreciated.

Max avatar
Max
User
Posts: 221
Joined: 14-Jul-2006
# Posted on: 23-Oct-2007 09:07:43   

jshallard wrote:

Any ideas / debug techniques on how to track down exactly where the collection is altered would be much appreciated.

Maybe you can try using the source of LLBLGen library, instead of the compiled DLL, so you can put breakpoint (or conditional breakpoint) in the llblgen source code handling the collection (property getter/setter add/delete method....) and when you find the collection's change you are looking for, you can look at the stack to understand what triggered this particular modification.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 23-Oct-2007 10:19:40   

When iterating through an entity collection using a foreach loop I get the following error:

“Collection was modified; enumeration operation may not execute”

Most probably this exception occurs when an entity is deleted from the collection being looped. Try to keep an eye on the collection.Count property. (put it in the watch).

Also you may try using the normal for loop -> for(int index = 0; index< collection.Count; index++)

jshallard
User
Posts: 62
Joined: 23-Mar-2005
# Posted on: 23-Oct-2007 16:03:32   

Thanks Walaa

I didn't realize that a "watch" would still work, even when a variable went of of scope... thanks for the tip

I don't do any deleting from a collection in the related code - which was why it was so hard to pin down.

Using a for-each loop would still be a problem, as the collection count would change in the middle of looping, which would cause a bunch of problems if its own.

I eventually managed to track down the code the caused the change by using the "stack" debug window - which allows you to jump back and forward down the path of execution, and check the value in previous variables.

The code that actually was causing the problem was where the same ShopEntity was being fetched again elsewhere... I did not realize that this would effect a related collection in a different scope. I guess i need to read up about LLBL Context a little more - any tips on that front would be welcome.