diff --git a/Source/EntityFramework.Extended/Dynamic/DynamicQueryable.cs b/Source/EntityFramework.Extended/Dynamic/DynamicQueryable.cs index 20dced3..9620b93 100644 --- a/Source/EntityFramework.Extended/Dynamic/DynamicQueryable.cs +++ b/Source/EntityFramework.Extended/Dynamic/DynamicQueryable.cs @@ -285,8 +285,20 @@ public Type GetDynamicClass(IEnumerable properties) Type type; if (!classes.TryGetValue(signature, out type)) { - type = CreateDynamicClass(signature.properties); - classes.Add(signature, type); + // Upgrade the lock, and double check the dictionary to improve thread safety. + LockCookie cookie = rwLock.UpgradeToWriterLock(Timeout.Infinite); + try + { + if (!classes.TryGetValue(signature, out type)) + { + type = CreateDynamicClass(signature.properties); + classes.Add(signature, type); + } + } + finally + { + rwLock.DowngradeFromWriterLock(ref cookie); + } } return type; } @@ -298,34 +310,26 @@ public Type GetDynamicClass(IEnumerable properties) Type CreateDynamicClass(DynamicProperty[] properties) { - LockCookie cookie = rwLock.UpgradeToWriterLock(Timeout.Infinite); - try - { - string typeName = "DynamicClass" + (classCount + 1); + string typeName = "DynamicClass" + (classCount + 1); #if ENABLE_LINQ_PARTIAL_TRUST new ReflectionPermission(PermissionState.Unrestricted).Assert(); #endif - try - { - TypeBuilder tb = this.module.DefineType(typeName, TypeAttributes.Class | - TypeAttributes.Public, typeof(DynamicClass)); - FieldInfo[] fields = GenerateProperties(tb, properties); - GenerateEquals(tb, fields); - GenerateGetHashCode(tb, fields); - Type result = tb.CreateType(); - classCount++; - return result; - } - finally - { -#if ENABLE_LINQ_PARTIAL_TRUST - PermissionSet.RevertAssert(); -#endif - } + try + { + TypeBuilder tb = this.module.DefineType(typeName, TypeAttributes.Class | + TypeAttributes.Public, typeof(DynamicClass)); + FieldInfo[] fields = GenerateProperties(tb, properties); + GenerateEquals(tb, fields); + GenerateGetHashCode(tb, fields); + Type result = tb.CreateType(); + classCount++; + return result; } finally { - rwLock.DowngradeFromWriterLock(ref cookie); +#if ENABLE_LINQ_PARTIAL_TRUST + PermissionSet.RevertAssert(); +#endif } }