The exception below is caused by that LinkDataBackingTypeResolverInterceptor.TryResolveType can be called multiple times in parallel. The method does only validate if a type is in the dictionary at the beginning and later calls the Add method on the dictionary if it was resolved, it can result in an exception being thrown if another thread has already resolved and added the type.
I suggest changing to calling TryAdd on the dictionary or using some kind of locking.
Screenshot from just before the exception:
You can see in the IEnumerableVisualizer that two types is present in the dictionary and in the Watch window you can see that a duplicate value is about to be added.
Logged Exception:
[ERR] Initialize action failed for 'Initialize on class EPiServer.Initialization.Internal.ModelSyncInitialization, EPiServer, Version=12.19.0.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7'
System.AggregateException: One or more errors occurred. (An item with the same key has already been added. Key: XXXXXXX.Features.Linkdata.Models.IconLinkBase)
---> System.ArgumentException: An item with the same key has already been added. Key: XXXXXXX.Features.Linkdata.Models.IconLinkBase
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at Geta.Optimizely.GenericLinks.Cms.Registration.LinkDataBackingTypeResolverInterceptor.TryResolveType(Type type, Type baseType)
at Geta.Optimizely.GenericLinks.Cms.Registration.LinkDataBackingTypeResolverInterceptor.Resolve(Type type)
at EPiServer.DataAbstraction.RuntimeModel.Internal.PropertyDefinitionSynchronizer.ResolveType(PropertyDefinitionModel model)
at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelRegister.ValidateChangeOfModelType(PropertyDefinitionModel propertyModel, String modelName)
at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelRegister.SetStateForPropertyDefinitionModels(ContentTypeModel model)
at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelRegister.<AnalyzeProperties>b__15_0(ContentTypeModel model)
at System.Threading.Tasks.Parallel.<>c__DisplayClass33_0`2.<ForEachWorker>b__0(Int32 i)
at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
--- End of stack trace from previous location ---
at System.Threading.Tasks.Parallel.<>c__DisplayClass19_0`1.<ForWorker>b__1(RangeWorker& currentWorker, Int32 timeout, Boolean& replicationDelegateYieldedBeforeCompletion)
at System.Threading.Tasks.TaskReplicator.Replica.Execute()
--- End of inner exception stack trace ---
at System.Threading.Tasks.TaskReplicator.Run[TState](ReplicatableUserAction`1 action, ParallelOptions options, Boolean stopOnFirstFailure)
at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
--- End of stack trace from previous location ---
at System.Threading.Tasks.Parallel.ThrowSingleCancellationExceptionOrOtherException(ICollection exceptions, CancellationToken cancelToken, Exception otherException)
at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IList`1 list, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IEnumerable`1 source, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.ForEach[TSource](IEnumerable`1 source, Action`1 body)
at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelRegister.AnalyzeProperties()
at EPiServer.DataAbstraction.RuntimeModel.Internal.ContentTypeModelScanner.Sync(Boolean forceCommit)
at EPiServer.Initialization.Internal.ModelSyncInitialization.Initialize(InitializationEngine context)
at EPiServer.Framework.Initialization.Internal.ModuleNode.Execute(Action a, String key)
at EPiServer.Framework.Initialization.Internal.ModuleNode.Initialize(InitializationEngine context)
at EPiServer.Framework.Initialization.InitializationEngine.InitializeModules()
Geta-Optimmizely-GenericLinks Version: 1.8.1 Optimizely Version: 12.24.0
The exception below is caused by that
LinkDataBackingTypeResolverInterceptor.TryResolveType
can be called multiple times in parallel. The method does only validate if a type is in the dictionary at the beginning and later calls the Add method on the dictionary if it was resolved, it can result in an exception being thrown if another thread has already resolved and added the type.I suggest changing to calling
TryAdd
on the dictionary or using some kind of locking.Screenshot from just before the exception: You can see in the IEnumerableVisualizer that two types is present in the dictionary and in the Watch window you can see that a duplicate value is about to be added.
Logged Exception: