3
Vote

Collection was modified exception in SerializationHelper.Save

description

I just came across this exception, and it was during a SaveAsync call:
10:26:32.3774 ERROR [Thread:1][DataRepository] - Collection was modified; enumeration operation may not execute.
   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()
   at System.Collections.Generic.Dictionary`2..ctor(IDictionary`2 dictionary, IEqualityComparer`1 comparer)
   at System.Collections.Generic.Dictionary`2..ctor(IDictionary`2 dictionary)
   at Wintellect.Sterling.Serialization.SerializationHelper.Save(Type type, Object instance, BinaryWriter bw, CycleCache cache, Boolean saveTypeExplicit)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.Save(Type actualType, Type tableType, Object instance, CycleCache cache)
   at Wintellect.Sterling.Serialization.SerializationHelper._SerializeClass(Type type, String propertyName, Object foreignTable, BinaryWriter bw, CycleCache cache)
   at Wintellect.Sterling.Serialization.SerializationHelper._InnerSave(Type type, String propertyName, Object instance, BinaryWriter bw, CycleCache cache)
   at Wintellect.Sterling.Serialization.SerializationHelper._SaveList(IList list, BinaryWriter bw, CycleCache cache)
   at Wintellect.Sterling.Serialization.SerializationHelper._InnerSave(Type type, String propertyName, Object instance, BinaryWriter bw, CycleCache cache)
   at Wintellect.Sterling.Serialization.SerializationHelper.Save(Type type, Object instance, BinaryWriter bw, CycleCache cache, Boolean saveTypeExplicit)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.Save(Type actualType, Type tableType, Object instance, CycleCache cache)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.Save(Type type, Object instance)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.<>c__DisplayClass12.<SaveAsync>b__11(Object o, DoWorkEventArgs e)
   at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
   at System.ComponentModel.BackgroundWorker.OnRun(Object argument)
I think it has to do with this piece of code in SerializationHelper.Save:
// now iterate the serializable properties - create a copy to avoid multi-threaded conflicts
foreach (var p in new Dictionary<string, SerializationCache>(_propertyCache[type]))
{
    var serializationCache = p.Value;
    var value = serializationCache.GetMethod(instance);
    _InnerSave(value == null ? serializationCache.PropType : value.GetType(), serializationCache.PropertyName, value, bw, cache);
}

comments

kayub wrote Mar 4, 2013 at 3:52 AM

I think this would also explain further exceptions after this:
10:30:26.3931 ERROR [Thread:1][DataRepository] - There was an issue accessing isolated storage: Operation not permitted on IsolatedStorageFileStream.. Check the inner exception for details.
   at Wintellect.Sterling.IsolatedStorage.IsoStorageHelper.GetWriter(String path)
   at Wintellect.Sterling.IsolatedStorage.IsolatedStorageDriver.Save(Type type, Int32 keyIndex, Byte[] bytes)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.Save(Type actualType, Type tableType, Object instance, CycleCache cache)
   at Wintellect.Sterling.Serialization.SerializationHelper._SerializeClass(Type type, String propertyName, Object foreignTable, BinaryWriter bw, CycleCache cache)
   at Wintellect.Sterling.Serialization.SerializationHelper._InnerSave(Type type, String propertyName, Object instance, BinaryWriter bw, CycleCache cache)
   at Wintellect.Sterling.Serialization.SerializationHelper.Save(Type type, Object instance, BinaryWriter bw, CycleCache cache, Boolean saveTypeExplicit)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.Save(Type actualType, Type tableType, Object instance, CycleCache cache)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.Save(Type type, Object instance)
   at Wintellect.Sterling.Database.BaseDatabaseInstance.<>c__DisplayClass12.<SaveAsync>b__11(Object o, DoWorkEventArgs e)
   at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
   at System.ComponentModel.BackgroundWorker.OnRun(Object argument)

wrote Mar 5, 2013 at 5:27 PM

kayub wrote Mar 7, 2013 at 11:29 PM

Hmm, maybe not. I switched that line to use a SafeDictionary (that uses a lock) but I still run into it.

wrote Mar 14, 2013 at 11:04 AM