Multi-Threaded loading


Hi Jeremy,
I already send you a tweet today about my multi-threading issue with Sterling. I have up to three threads that are trying to load a, prior not loaded entry with sterling. From my opinion, only the first should try to load it, the second should get the cached entry.
But still, I get the following exception (not always ,but considerable often).
System.InvalidOperationException was unhandled
bei System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
bei System.Collections.Generic.List`1.Enumerator.MoveNext()
bei Wintellect.Sterling.Serialization.SerializationHelper.Load(Type type, Object key, BinaryReader br, CycleCache cache)
bei Wintellect.Sterling.Database.BaseDatabaseInstance.Load(Type type, Object key, CycleCache cache)
bei Wintellect.Sterling.Database.BaseDatabaseInstance.Load(Type type, Object key)
bei Wintellect.Sterling.Database.BaseDatabaseInstance.Load[T](Object key)
bei MyProject.DataAccess.ProjectDao.ProjectSterlingDao.LoadProject(Guid projectId)
bei MyProject.BusinessComponents.ProjectService.ProjectService.LoadProject(Guid projectId)
bei MyProject.BusinessComponents.TimeEntryService.TimeEntryService.EnrichTimeEntries(List`1 entries)
bei MyProject.BusinessComponents.TimeEntryService.TimeEntryService.SearchTimeEntries(ITimeEntryFilter filter)
bei MyProject.ViewModels.Overview.OverviewVm.<OnUpdateEntries>b__c(Object async)
bei System.Threading.ThreadPool.WorkItem.doWork(Object o)
bei System.Threading.Timer.ring()
In my opinion this looks like an internal bug in Sterling. BTW, I'm using the Release 1.0 RTM.
UPDATE: It seems to occure only when I use the RELEASE Version of the Wintellect.Sterling.WindowsPhone DLLs.
UPDATE2: I'm currently debugging that issue and it seems that the _propertyCache is not thread safe, because the exception occurs when iterating the propertyCache. And I expect, that another thread changed the Dictionary. Method: SerializationHelper.Load - Line 366
But as I said: It only occures, on a real phone, with a Release Build ( where I set the Debug Info to FULL )
        // now iterate
        foreach (var p in _propertyCache[type])
            p.SetMethod(instance, _Deserialize(br, cache));
        return instance;
Thx for your help.
  • Gerhard
Closed Apr 10, 2011 at 3:12 AM by jeremylikness


jeremylikness wrote Apr 4, 2011 at 9:52 PM

Is it possible for you to test the code with the latest change set? Only reason I ask is because I believe the issue above is addressed now. The problem was that the actual key collection was being returned in the previous version, which of course would result in issues when multiple sources tried to iterate it. The newer version passes back a copy of the collection so there should not be a collision - but I wanted you to check to make sure. If so, the fix for 1.0 is simple and you simply return a new List<yada>() in the base database interface for the key and index collections (pass in the existing collection to the new list declaration to create the copy).

wrote Apr 4, 2011 at 10:09 PM

BitKFu wrote Apr 4, 2011 at 10:10 PM

Thanx for your reply. I try to use the latest changeset. Give me a moment to check.

BitKFu wrote Apr 4, 2011 at 10:19 PM

When I use the latest changeset, all my data is gone. So I can't say, if the latest changeset would work ...
Do you have any idea, why I can't see my data? If I change the Sterling DLL to the release, my data is visible again.
PS: I'll go to bed now ;)

jeremylikness wrote Apr 4, 2011 at 10:48 PM

BitKFu wrote Apr 5, 2011 at 8:17 PM

My debugging showed, that two threads running the following foreach the same time, which causes the bug:

SerializationHelper.Load - Line 366

// now iterate
foreach (var p in _propertyCache[type])
p.SetMethod(instance, _Deserialize(br, cache));

In my opinion this should be no problem, but in fact, it is. So I try to lock this and see what happens.

jeremylikness wrote Apr 5, 2011 at 8:46 PM

Great catch. I lock the path but if you have two different types that have a similar sub type this collision can occur. Now that I know the signature I'll confirm the test, add the fix and let you know how to retro it to 1.0.

BitKFu wrote Apr 5, 2011 at 9:43 PM

Yep, that might be the problem. I have two classes with the same base class. The first contains a list of the second one.

class A : baseClass { list<B> childList }
class B : baseClass

The two threads trying to read instance of A. Huh ;)

BitKFu wrote Apr 5, 2011 at 9:46 PM

Thx in advance for the fix. I really appreciate your help.

wrote Apr 10, 2011 at 3:12 AM

Resolved with changeset 75964.

jeremylikness wrote Apr 10, 2011 at 11:15 PM

Let me know if this works for you - if not I'll re-open. Thanks.

BitKFu wrote Apr 15, 2011 at 7:57 AM

Hi Jeremy,
yes, that seemed to fix it. Thanks for your help.

wrote Feb 21, 2013 at 11:49 PM

wrote May 16, 2013 at 11:30 AM