/* * Non-recursive version of object descend. this consumes more memory than recursive in-depth * traversal but prevents stack overflows on long chains of objects * or complex graphs (a max. recursion depth on my machine was ~5000 objects linked in a chain * so not too much). */ private static long MeasureObjectSize(object root) { // Objects seen so far. IdentityHashSet <object> seen = new IdentityHashSet <object>(); // Class cache with reference Field and precalculated shallow size. IDictionary <Type, ClassCache> classCache = new JCG.Dictionary <Type, ClassCache>(IdentityEqualityComparer <Type> .Default); // Stack of objects pending traversal. Recursion caused stack overflows. Stack <object> stack = new Stack <object>(); stack.Push(root); long totalSize = 0; while (stack.Count > 0) { object ob = stack.Pop(); if (ob is null || seen.Contains(ob)) { continue; } seen.Add(ob); Type obClazz = ob.GetType(); // LUCENENET specific - .NET cannot return a null type for an object, so no need to assert it if (obClazz.Equals(typeof(string))) { // LUCENENET specific - we can get a closer estimate of a string // by using simple math. Reference: http://stackoverflow.com/a/8171099. // This fixes the TestSanity test. totalSize += (2 * (((string)ob).Length + 1)); } if (obClazz.IsArray) { /* * Consider an array, possibly of primitive types. Push any of its references to * the processing stack and accumulate this array's shallow size. */ long size = NUM_BYTES_ARRAY_HEADER; Array array = (Array)ob; int len = array.Length; if (len > 0) { Type componentClazz = obClazz.GetElementType(); if (componentClazz.IsPrimitive) { size += (long)len * primitiveSizes[componentClazz]; } else { size += (long)NUM_BYTES_OBJECT_REF * len; // Push refs for traversal later. for (int i = len; --i >= 0;) { object o = array.GetValue(i); if (o != null && !seen.Contains(o)) { stack.Push(o); } } } } totalSize += AlignObjectSize(size); } else { /* * Consider an object. Push any references it has to the processing stack * and accumulate this object's shallow size. */ try { if (!classCache.TryGetValue(obClazz, out ClassCache cachedInfo) || cachedInfo is null) { classCache[obClazz] = cachedInfo = CreateCacheEntry(obClazz); } foreach (FieldInfo f in cachedInfo.ReferenceFields) { // Fast path to eliminate redundancies. object o = f.GetValue(ob); if (o != null && !seen.Contains(o)) { stack.Push(o); } } totalSize += cachedInfo.AlignedShallowInstanceSize; } catch (Exception e) when(e.IsIllegalAccessException()) { // this should never happen as we enabled setAccessible(). throw RuntimeException.Create("Reflective field access failed?", e); } } } // Help the GC (?). seen.Clear(); stack.Clear(); classCache.Clear(); return(totalSize); }
/* * Non-recursive version of object descend. this consumes more memory than recursive in-depth * traversal but prevents stack overflows on long chains of objects * or complex graphs (a max. recursion depth on my machine was ~5000 objects linked in a chain * so not too much). */ private static long MeasureObjectSize(object root) { // Objects seen so far. IdentityHashSet <object> seen = new IdentityHashSet <object>(); // Class cache with reference Field and precalculated shallow size. HashMap <Type, ClassCache> classCache = new HashMap <Type, ClassCache>(); // Stack of objects pending traversal. Recursion caused stack overflows. Stack <object> stack = new Stack <object>(); stack.Push(root); long totalSize = 0; while (stack.Count > 0) { object ob = stack.Pop(); if (ob == null || seen.Contains(ob)) { continue; } seen.Add(ob); Type obClazz = ob.GetType(); if (obClazz.IsArray) { /* * Consider an array, possibly of primitive types. Push any of its references to * the processing stack and accumulate this array's shallow size. */ long size = NUM_BYTES_ARRAY_HEADER; Array array = (Array)ob; int len = array.Length; if (len > 0) { Type componentClazz = obClazz.GetElementType(); if (componentClazz.IsPrimitive) { size += (long)len * PrimitiveSizes[componentClazz]; } else { size += (long)NUM_BYTES_OBJECT_REF * len; // Push refs for traversal later. for (int i = len; --i >= 0;) { object o = array.GetValue(i); if (o != null && !seen.Contains(o)) { stack.Push(o); } } } } totalSize += AlignObjectSize(size); } else { /* * Consider an object. Push any references it has to the processing stack * and accumulate this object's shallow size. */ try { ClassCache cachedInfo = classCache[obClazz]; if (cachedInfo == null) { classCache[obClazz] = cachedInfo = CreateCacheEntry(obClazz); } foreach (FieldInfo f in cachedInfo.ReferenceFields) { // Fast path to eliminate redundancies. object o = f.GetValue(ob); if (o != null && !seen.Contains(o)) { stack.Push(o); } } totalSize += cachedInfo.AlignedShallowInstanceSize; } catch (Exception e) { // this should never happen as we enabled setAccessible(). throw new Exception("Reflective field access failed?", e); } } } // Help the GC (?). seen.Clear(); stack.Clear(); classCache.Clear(); return(totalSize); }
protected void FilterWrongRelationMappings(IISet <RelationMember> relationMembers) { // filter all relations which can not be a relation because of explicit embedded property mapping IdentityHashSet <RelationMember> toRemove = new IdentityHashSet <RelationMember>(); foreach (RelationMember relationMember in relationMembers) { String[] memberPath = EmbeddedMember.Split(relationMember.Name); foreach (RelationMember otherRelationMember in relationMembers) { if (Object.ReferenceEquals(relationMember, otherRelationMember) || toRemove.Contains(otherRelationMember)) { continue; } if (!(otherRelationMember is IEmbeddedMember)) { // only embedded members can help identifying other wrong relation members continue; } String[] otherMemberPath = ((IEmbeddedMember)otherRelationMember).GetMemberPathToken(); if (memberPath.Length > otherMemberPath.Length) { continue; } bool match = true; for (int a = 0, size = memberPath.Length; a < size; a++) { if (!memberPath[a].Equals(otherMemberPath[a])) { match = false; break; } } if (match) { toRemove.Add(relationMember); break; } } } relationMembers.RemoveAll(toRemove); }
public void AddMembers(EntityMetaData metaData, IEntityConfig entityConfig) { Type realType = entityConfig.RealType; ISet <String> memberNamesToIgnore = new HashSet <String>(); ISet <String> explicitBasicMemberNames = new HashSet <String>(); IList <IMemberConfig> embeddedMembers = new List <IMemberConfig>(); IMap <String, IMemberConfig> nameToMemberConfig = new HashMap <String, IMemberConfig>(); IMap <String, IRelationConfig> nameToRelationConfig = new HashMap <String, IRelationConfig>(); IdentityLinkedMap <String, Member> nameToMemberMap = new IdentityLinkedMap <String, Member>(); FillNameCollections(entityConfig, memberNamesToIgnore, explicitBasicMemberNames, embeddedMembers, nameToMemberConfig, nameToRelationConfig); IdentityLinkedSet <PrimitiveMember> alternateIdMembers = new IdentityLinkedSet <PrimitiveMember>(); IdentityLinkedSet <PrimitiveMember> primitiveMembers = new IdentityLinkedSet <PrimitiveMember>(); IdentityLinkedSet <RelationMember> relationMembers = new IdentityLinkedSet <RelationMember>(); IdentityLinkedSet <Member> notMergeRelevant = new IdentityLinkedSet <Member>(); IdentityLinkedSet <Member> containedInAlternateIdMember = new IdentityLinkedSet <Member>(); IPropertyInfo[] properties = PropertyInfoProvider.GetProperties(realType); IdentityLinkedMap <String, Member> explicitlyConfiguredMemberNameToMember = new IdentityLinkedMap <String, Member>(); HashMap <String, IOrmConfig> nameToConfigMap = new HashMap <String, IOrmConfig>(); // Resolve members for all explicit configurations - both simple and composite ones, each with embedded // functionality (dot-member-path) foreach (IMemberConfig memberConfig in entityConfig.GetMemberConfigIterable()) { PutNameToConfigMap(memberConfig, nameToConfigMap); if (memberConfig.Ignore) { continue; } HandleMemberConfig(metaData, realType, memberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); } foreach (IRelationConfig relationConfig in entityConfig.GetRelationConfigIterable()) { PutNameToConfigMap(relationConfig, nameToConfigMap); HandleRelationConfig(realType, relationConfig, explicitlyConfiguredMemberNameToMember); } PutNameToConfigMap(entityConfig.IdMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.VersionMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.CreatedByMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.CreatedOnMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.UpdatedByMemberConfig, nameToConfigMap); PutNameToConfigMap(entityConfig.UpdatedOnMemberConfig, nameToConfigMap); metaData.IdMember = HandleMemberConfig(metaData, realType, entityConfig.IdMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.VersionMember = HandleMemberConfig(metaData, realType, entityConfig.VersionMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.CreatedByMember = HandleMemberConfig(metaData, realType, entityConfig.CreatedByMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.CreatedOnMember = HandleMemberConfig(metaData, realType, entityConfig.CreatedOnMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.UpdatedByMember = HandleMemberConfig(metaData, realType, entityConfig.UpdatedByMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); metaData.UpdatedOnMember = HandleMemberConfig(metaData, realType, entityConfig.UpdatedOnMemberConfig, explicitlyConfiguredMemberNameToMember, nameToMemberMap); IdentityHashSet <Member> idMembers = new IdentityHashSet <Member>(); Member idMember = metaData.IdMember; if (idMember is CompositeIdMember) { idMembers.AddAll(((CompositeIdMember)idMember).Members); } else { idMembers.Add(idMember); } // Handle all explicitly configured members foreach (Entry <String, Member> entry in explicitlyConfiguredMemberNameToMember) { String memberName = entry.Key; IOrmConfig ormConfig = nameToConfigMap.Get(memberName); Member member = entry.Value; if (idMembers.Contains(member)) { continue; } if (ormConfig.ExplicitlyNotMergeRelevant) { notMergeRelevant.Add(member); } if (ormConfig is IRelationConfig) { if (!relationMembers.Add((RelationMember)member)) { throw new Exception("Member has been registered as relation multiple times: " + member.Name); } continue; } if (!(ormConfig is IMemberConfig)) { continue; } if (((IMemberConfig)ormConfig).AlternateId) { if (!alternateIdMembers.Add((PrimitiveMember)member)) { throw new Exception("Member has been registered as alternate id multiple times: " + member.Name); } if (member is CompositeIdMember) { Member[] containedMembers = ((CompositeIdMember)member).Members; containedInAlternateIdMember.AddAll(containedMembers); } } if (!(member is CompositeIdMember) && metaData.VersionMember != member) { // Alternate Ids are normally primitives, too. But Composite Alternate Ids not - only their composite // items are primitives primitiveMembers.Add((PrimitiveMember)member); } } IdentityHashSet <String> explicitTypeInfoItems = IdentityHashSet <String> .Create(explicitlyConfiguredMemberNameToMember.Count); foreach (Entry <String, Member> entry in explicitlyConfiguredMemberNameToMember) { Member member = entry.Value; explicitTypeInfoItems.Add(member.Name); if (member is IEmbeddedMember) { explicitTypeInfoItems.Add(((IEmbeddedMember)member).GetMemberPath()[0].Name); } } // Go through the available members to look for potential auto-mapping (simple, no embedded) for (int i = 0; i < properties.Length; i++) { IPropertyInfo property = properties[i]; String memberName = property.Name; if (memberNamesToIgnore.Contains(memberName)) { continue; } if (explicitTypeInfoItems.Contains(memberName)) { // already configured, no auto mapping needed for this member continue; } MethodPropertyInfo mProperty = (MethodPropertyInfo)property; Type elementType = TypeInfoItemUtil.GetElementTypeUsingReflection(mProperty.Getter.ReturnType, null); if ((nameToMemberMap.Get(property.Name) is RelationMember) || RelationProvider.IsEntityType(elementType)) { RelationMember member = GetRelationMember(metaData.EntityType, property, nameToMemberMap); relationMembers.Add(member); continue; } PrimitiveMember member2 = GetPrimitiveMember(metaData.EntityType, property, nameToMemberMap); if (metaData.IdMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_ID)) { metaData.IdMember = member2; continue; } if (idMembers.Contains(member2) && !alternateIdMembers.Contains(member2) && !containedInAlternateIdMember.Contains(member2)) { continue; } if (member2.Equals(metaData.IdMember) || member2.Equals(metaData.VersionMember) || member2.Equals(metaData.CreatedByMember) || member2.Equals(metaData.CreatedOnMember) || member2.Equals(metaData.UpdatedByMember) || member2.Equals(metaData.UpdatedOnMember)) { continue; } if (metaData.VersionMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_VERSION)) { metaData.VersionMember = member2; continue; } if (metaData.CreatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_BY)) { metaData.CreatedByMember = member2; } else if (metaData.CreatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_ON)) { metaData.CreatedOnMember = member2; } else if (metaData.UpdatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_BY)) { metaData.UpdatedByMember = member2; } else if (metaData.UpdatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_ON)) { metaData.UpdatedOnMember = member2; } primitiveMembers.Add(member2); } foreach (PrimitiveMember member in primitiveMembers) { String memberName = member.Name; if (explicitBasicMemberNames.Contains(memberName)) { // Even if the name would match, this member was explicitly configured as "basic" continue; } if (metaData.CreatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_BY)) { metaData.CreatedByMember = member; } else if (metaData.CreatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_CREATED_ON)) { metaData.CreatedOnMember = member; } else if (metaData.UpdatedByMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_BY)) { metaData.UpdatedByMember = member; } else if (metaData.UpdatedOnMember == null && memberName.Equals(EntityMetaData.DEFAULT_NAME_UPDATED_ON)) { metaData.UpdatedOnMember = member; } } FilterWrongRelationMappings(relationMembers); // Order of setter calls is important PrimitiveMember[] primitives = primitiveMembers.ToArray(); PrimitiveMember[] alternateIds = alternateIdMembers.ToArray(); RelationMember[] relations = relationMembers.ToArray(); Array.Sort(primitives); Array.Sort(alternateIds); Array.Sort(relations); metaData.PrimitiveMembers = primitives; metaData.AlternateIdMembers = alternateIds; metaData.RelationMembers = relations; foreach (Member member in notMergeRelevant) { metaData.SetMergeRelevant(member, false); } if (metaData.IdMember == null) { throw new Exception("No ID member could be resolved for entity of type " + metaData.RealType); } }
protected virtual void RevertChangesIntern(IRevertChangesSavepoint savepoint, IList <Object> objectsToRevert, bool globally, RevertChangesFinishedCallback revertChangesFinishedCallback) { // Store the RevertChangesFinishedCallback from this thread on the stack and set the property null (for following calls): if (objectsToRevert == null || objectsToRevert.Count == 0) { if (revertChangesFinishedCallback != null) { revertChangesFinishedCallback.Invoke(true); } return; } if (globally) { GuiThreadHelper.InvokeOutOfGui(delegate() { bool success = false; try { DataChangeEvent dataChange = new DataChangeEvent(); dataChange.IsLocalSource = true; dataChange.Inserts = new List <IDataChangeEntry>(0); dataChange.Updates = new List <IDataChangeEntry>(); dataChange.Deletes = new List <IDataChangeEntry>(); for (int a = objectsToRevert.Count; a-- > 0;) { Object objectToRevert = objectsToRevert[a]; IEntityMetaData metaData = ((IEntityMetaDataHolder)objectToRevert).Get__EntityMetaData(); Object id = metaData.IdMember.GetValue(objectToRevert, false); if (id == null) { dataChange.Deletes.Add(new DirectDataChangeEntry(objectToRevert)); continue; } dataChange.Updates.Add(new DataChangeEntry(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null)); } EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1); success = true; } finally { if (revertChangesFinishedCallback != null) { revertChangesFinishedCallback.Invoke(success); } } }); } else { // Commented the following part from Ambeth 0.130 and use the part from Ambeth 0.129 due to a deadlock in the merge process: //GuiThreadHelper.InvokeOutOfGui(delegate() //{ // bool success1 = false; // try // { // IList<IDataChangeEntry> directObjectDeletes = new List<IDataChangeEntry>(); // IList<Object> initializedObjects = MergeController.ScanForInitializedObjects(objectsToRevert, true, null); // IList<IObjRef> orisToRevert = new List<IObjRef>(); // ISet<Object> persistedObjectsToRevert = new IdentityHashSet<Object>(); // for (int a = initializedObjects.Count; a-- > 0; ) // { // Object objectToRevert = initializedObjects[a]; // IEntityMetaData metaData = EntityMetaDataProvider.GetMetaData(objectToRevert.GetType()); // Object id = metaData.IdMember.GetValue(objectToRevert, false); // if (id == null) // { // directObjectDeletes.Add(new DirectDataChangeEntry(objectToRevert)); // continue; // } // persistedObjectsToRevert.Add(objectToRevert); // orisToRevert.Add(new ObjRef(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null)); // } // IList<Object> hardRefsToRootCacheValues = RootCache.GetObjects(orisToRevert, CacheDirective.CacheValueResult | CacheDirective.ReturnMisses); // for (int a = orisToRevert.Count; a-- > 0; ) // { // if (hardRefsToRootCacheValues[a] == null) // { // // Object could not be loaded/retrieved any more. So the ori refers to an invalid object // // We can not revert invalid objects and currently ignore them. They will raise exceptions if they will // // be tried to persist in a merge process any time in the future // orisToRevert.RemoveAt(a); // } // } // // We do nothing with the hardRef-list from the RootCache. It is only necessary to keep track of the instance reference on the stack // // To prohibit GC any potential WeakReferences in the meantime.... // GuiThreadHelper.InvokeInGuiAndWait(delegate() // { // IProcessResumeItem processResumeItem = WaitEventToResume(); // try // { // bool oldCacheModificationValue = CacheModification.IsActive; // CacheModification.IsActive = true; // bool oldFailEarlyModeActive = AbstractCache<Object>.FailEarlyModeActive; // AbstractCache<Object>.FailEarlyModeActive = true; // try // { // IList<IWritableCache> firstLevelCaches = FirstLevelCacheManager.SelectFirstLevelCaches(); // IList<Object> hardRefsToRootCacheValuesHere = hardRefsToRootCacheValues; // foreach (IWritableCache firstLevelCache in firstLevelCaches) // { // IList<Object> persistedObjectsInThisCache = firstLevelCache.GetObjects(orisToRevert, CacheDirective.FailEarly); // for (int a = persistedObjectsInThisCache.Count; a-- > 0; ) // { // Object persistedObjectInThisCache = persistedObjectsInThisCache[a]; // if (!persistedObjectsToRevert.Contains(persistedObjectInThisCache)) // { // continue; // } // RootCache.ApplyValues(persistedObjectInThisCache, (ICacheIntern)firstLevelCache); // } // } // for (int a = objectsToRevert.Count; a-- > 0; ) // { // Object objectToRevert = objectsToRevert[a]; // if (objectToRevert is IDataObject) // { // // Objects which are specified to be reverted loose their delete flag // ((IDataObject)objectToRevert).ToBeDeleted = false; // } // } // } // finally // { // AbstractCache<Object>.FailEarlyModeActive = oldFailEarlyModeActive; // CacheModification.IsActive = oldCacheModificationValue; // } // } // finally // { // if (processResumeItem != null) // { // processResumeItem.ResumeProcessingFinished(); // processResumeItem = null; // } // } // }); // if (directObjectDeletes.Count > 0) // { // DataChangeEvent dataChange = DataChangeEvent.Create(0, 0, 0); // dataChange.Deletes = directObjectDeletes; // EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1); // } // success1 = true; // } // finally // { // if (revertChangesFinishedCallback != null) // { // revertChangesFinishedCallback.Invoke(success1); // } // } //}); // Here comes the part from Ambeth 0.129: GuiThreadHelper.InvokeOutOfGui(delegate() { bool success1 = false; bool?success2 = null; bool?success3 = null; try { IList <IDataChangeEntry> directObjectDeletes = new List <IDataChangeEntry>(); List <IObjRef> objRefs = new List <IObjRef>(); List <ValueHolderRef> valueHolderKeys = new List <ValueHolderRef>(); IList <Object> initializedObjects = MergeController.ScanForInitializedObjects(objectsToRevert, true, null, objRefs, valueHolderKeys); IList <IObjRef> orisToRevert = new List <IObjRef>(); ISet <Object> persistedObjectsToRevert = new IdentityHashSet <Object>(); for (int a = initializedObjects.Count; a-- > 0;) { Object objectToRevert = initializedObjects[a]; IEntityMetaData metaData = ((IEntityMetaDataHolder)objectToRevert).Get__EntityMetaData(); Object id = metaData.IdMember.GetValue(objectToRevert, false); if (id == null) { directObjectDeletes.Add(new DirectDataChangeEntry(objectToRevert)); continue; } persistedObjectsToRevert.Add(objectToRevert); orisToRevert.Add(new ObjRef(metaData.EntityType, ObjRef.PRIMARY_KEY_INDEX, id, null)); } IList <Object> hardRefsToRootCacheValues = RootCache.GetObjects(orisToRevert, CacheDirective.CacheValueResult | CacheDirective.ReturnMisses); for (int a = orisToRevert.Count; a-- > 0;) { if (hardRefsToRootCacheValues[a] == null) { // Object could not be loaded/retrieved any more. So the ori refers to an invalid object // We can not revert invalid objects and currently ignore them. They will raise exceptions if they will // be tried to persist in a merge process any time in the future orisToRevert.RemoveAt(a); } } // We do nothing with the hardRef-list from the RootCache. It is only necessary to keep track of the instance reference on the stack // To prohibit GC any potential WeakReferences in the meantime.... success2 = false; GuiThreadHelper.InvokeInGui(delegate(Object state) { WaitEventToResume(delegate(IProcessResumeItem processResumeItem) { try { bool oldCacheModificationValue = CacheModification.Active; CacheModification.Active = true; bool oldFailEarlyModeActive = AbstractCache.FailInCacheHierarchyModeActive; AbstractCache.FailInCacheHierarchyModeActive = true; try { IList <IWritableCache> firstLevelCaches = FirstLevelCacheManager.SelectFirstLevelCaches(); IList <Object> hardRefsToRootCacheValuesHere = hardRefsToRootCacheValues; foreach (IWritableCache firstLevelCache in firstLevelCaches) { IList <Object> persistedObjectsInThisCache = firstLevelCache.GetObjects(orisToRevert, CacheDirective.FailEarly); for (int a = persistedObjectsInThisCache.Count; a-- > 0;) { Object persistedObjectInThisCache = persistedObjectsInThisCache[a]; if (!persistedObjectsToRevert.Contains(persistedObjectInThisCache)) { continue; } RootCache.ApplyValues(persistedObjectInThisCache, (ICacheIntern)firstLevelCache, null); } } for (int a = objectsToRevert.Count; a-- > 0;) { Object objectToRevert = objectsToRevert[a]; if (objectToRevert is IDataObject) { // Objects which are specified to be reverted loose their flags ((IDataObject)objectToRevert).ToBeDeleted = false; } } if (directObjectDeletes.Count == 0) { success2 = true; return; } } finally { AbstractCache.FailInCacheHierarchyModeActive = oldFailEarlyModeActive; CacheModification.Active = oldCacheModificationValue; } } finally { if (processResumeItem != null) { processResumeItem.ResumeProcessingFinished(); } } success3 = false; GuiThreadHelper.InvokeOutOfGui(delegate() { try { DataChangeEvent dataChange = DataChangeEvent.Create(0, 0, 0); dataChange.Deletes = directObjectDeletes; EventDispatcher.DispatchEvent(dataChange, DateTime.Now, -1); success3 = true; } finally { if (revertChangesFinishedCallback != null) { revertChangesFinishedCallback.Invoke(success3.Value); } } }); success2 = true; }, delegate(Exception e) { if (revertChangesFinishedCallback != null && success3 == null) { revertChangesFinishedCallback.Invoke(success2.Value); } }); }, null); success1 = true; } finally { if (revertChangesFinishedCallback != null && success2 == null && success3 == null) { revertChangesFinishedCallback.Invoke(success1); } } }); } }