InfOracle
InfOracle

Reputation: 129

property function throws exception

I have a public property exposing a class manager (ViewManager) which manages what views are available to which users. This property (and several others) call a function called PopulateCollections() and then returns the private field _Views.

private bool _CollectionsPopulated = false;
public ViewManager Views { get { PopulateCollections(); return _Views;}}
void PopulateCollections()
{
    if (_CollectionsPopulated) return;
    _CollectionsPopulated = true;
    foreach (ClassTable item in ClassessTables)
    {
        item.ReflectMe();
    }
}

ClassTable is another class that stores the structure of a class within a database table. The function ReflectMe() calls upon each class item to acquire each classes' attrbiutes.

All this code works great. My problem is a timing one.

When the code runs, 99% of the time I have no issues. But for that 1%, the function PopulateCollections() takes too long and it causes an exception.

When parsing thru each available Model (each with their own group of ClassesTables), I get to this point where I'm looking at the Views...

If  ((ThisModel != null) && (ThisModel.Views != null))
{
    //Code here
}

When it gets to the "ThisModel.Views" which triggers PopulateCollections for the first time, when I hover over ThisModel.Views, I get the following:

"'ThisModel.Views' threw an exception of type 'System.InvalidOperationException'"

However, after a second longer, when I hover over it again, I get the actual values that I'm expecting. This tells me the PopulateCollections() code is still reflecting each class because when I run it without debugging, the exception thrown is

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

So...How do I make the code wait explicitly until this method is done?

Upvotes: 0

Views: 95

Answers (2)

InfOracle
InfOracle

Reputation: 129

My solution came from left field...the CLASS being populated was the issue. The code, however didn't tell me this, afterwards, the code as it was originally worked without a hitch.

Upvotes: 0

Brad Rem
Brad Rem

Reputation: 6026

What I think is deceiving is that your _CollectionsPopulated flag does not really indicate that the collection is fully populated. When you call the Views property twice, in quick succession, the second time it will return even though the collection is still being created.

I propose adding another flag which tracks the state of the collection. If the collection is in the middle of being filled in, don't try to repopulate it, but instead return null.

private bool _collectionsPopulating = false;
private bool _CollectionsPopulated = false;
public ViewManager Views 
{ 
     get 
     { 
         if (_collectionsPopulating) return null;
         PopulateCollections(); 
         return _collectionsPopulat_Views;
     }
}

void PopulateCollections()
{
    if (_CollectionsPopulated) return;
    _collectionsPopulating = true;
    foreach (ClassTable item in ClassessTables)
    {
        item.ReflectMe();
    }
    _CollectionsPopulated = true;
    _collectionsPopulating = false;
}

Upvotes: 1

Related Questions