diff --git a/Octokit/Http/SimpleJsonSerializer.cs b/Octokit/Http/SimpleJsonSerializer.cs index e450d66c1f..ba4fc52e3e 100644 --- a/Octokit/Http/SimpleJsonSerializer.cs +++ b/Octokit/Http/SimpleJsonSerializer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; @@ -34,7 +35,7 @@ internal static object DeserializeEnum(string value, Type type) class GitHubSerializerStrategy : PocoJsonSerializerStrategy { readonly List _membersWhichShouldPublishNull = new List(); - Dictionary> _cachedEnums = new Dictionary>(); + ConcurrentDictionary> _cachedEnums = new ConcurrentDictionary>(); protected override string MapClrMemberToJsonFieldName(MemberInfo member) { @@ -99,12 +100,11 @@ protected override object SerializeEnum(Enum p) internal object DeserializeEnumHelper(string value, Type type) { - if (!_cachedEnums.ContainsKey(type)) + var cachedEnumsForType = _cachedEnums.GetOrAdd(type, t => { - //First add type to Dictionary - _cachedEnums.Add(type, new Dictionary()); - - //then try to get all custom attributes, this happens only once per type + var enumsForType = new ConcurrentDictionary(); + + // Try to get all custom attributes, this happens only once per type var fields = type.GetRuntimeFields(); foreach (var field in fields) { @@ -113,25 +113,15 @@ internal object DeserializeEnumHelper(string value, Type type) var attribute = (ParameterAttribute)field.GetCustomAttribute(typeof(ParameterAttribute)); if (attribute != null) { - if (!_cachedEnums[type].ContainsKey(attribute.Value)) - { - var fieldValue = field.GetValue(null); - _cachedEnums[type].Add(attribute.Value, fieldValue); - } + enumsForType.GetOrAdd(attribute.Value, _ => field.GetValue(null)); } } - } - if (_cachedEnums[type].ContainsKey(value)) - { - return _cachedEnums[type][value]; - } - else - { - //dictionary does not contain enum value and has no custom attribute. So add it for future loops and return value - var parsed = Enum.Parse(type, value, ignoreCase: true); - _cachedEnums[type].Add(value, parsed); - return parsed; - } + + return enumsForType; + }); + + // If type cache does not contain enum value and has no custom attribute, add it for future loops + return cachedEnumsForType.GetOrAdd(value, v => Enum.Parse(type, value, ignoreCase: true)); } private string _type;