33
44using System . Collections ;
55using System . Collections . Generic ;
6+ using System . Collections . Concurrent ;
67using System . ComponentModel . Design ;
78using System . Diagnostics ;
89using System . Diagnostics . CodeAnalysis ;
@@ -23,10 +24,8 @@ namespace System.ComponentModel
2324 /// </summary>
2425 internal sealed partial class ReflectTypeDescriptionProvider : TypeDescriptionProvider
2526 {
26- // Hastable of Type -> ReflectedTypeData. ReflectedTypeData contains all
27- // of the type information we have gathered for a given type.
28- //
29- private Hashtable ? _typeData ;
27+ // ReflectedTypeData contains all of the type information we have gathered for a given type.
28+ private readonly ConcurrentDictionary < Type , ReflectedTypeData > _typeData = new ConcurrentDictionary < Type , ReflectedTypeData > ( ) ;
3029
3130 // This is the signature we look for when creating types that are generic, but
3231 // want to know what type they are dealing with. Enums are a good example of this;
@@ -81,8 +80,6 @@ internal sealed partial class ReflectTypeDescriptionProvider : TypeDescriptionPr
8180
8281 internal static Guid ExtenderProviderKey { get ; } = Guid . NewGuid ( ) ;
8382
84-
85- private static readonly object s_internalSyncObject = new object ( ) ;
8683 /// <summary>
8784 /// Creates a new ReflectTypeDescriptionProvider. The type is the
8885 /// type we will obtain type information for.
@@ -234,7 +231,7 @@ internal static void AddEditorTable(Type editorBaseType, Hashtable table)
234231 // don't throw; RTM didn't so we can't do it either.
235232 }
236233
237- lock ( s_internalSyncObject )
234+ lock ( TypeDescriptor . s_commonSyncObject )
238235 {
239236 Hashtable editorTables = EditorTables ;
240237 if ( ! editorTables . ContainsKey ( editorBaseType ) )
@@ -289,7 +286,6 @@ internal static void AddEditorTable(Type editorBaseType, Hashtable table)
289286 return obj ?? Activator . CreateInstance ( objectType , args ) ;
290287 }
291288
292-
293289 /// <summary>
294290 /// Helper method to create editors and type converters. This checks to see if the
295291 /// type implements a Type constructor, and if it does it invokes that ctor.
@@ -421,7 +417,7 @@ internal TypeConverter GetConverter([DynamicallyAccessedMembers(DynamicallyAcces
421417 //
422418 if ( table == null )
423419 {
424- lock ( s_internalSyncObject )
420+ lock ( TypeDescriptor . s_commonSyncObject )
425421 {
426422 table = editorTables [ editorBaseType ] ;
427423 if ( table == null )
@@ -838,22 +834,11 @@ internal Type[] GetPopulatedTypes(Module module)
838834 {
839835 List < Type > typeList = new List < Type > ( ) ;
840836
841- lock ( s_internalSyncObject )
837+ foreach ( KeyValuePair < Type , ReflectedTypeData > kvp in _typeData )
842838 {
843- Hashtable ? typeData = _typeData ;
844- if ( typeData != null )
839+ if ( kvp . Key . Module == module && kvp . Value ! . IsPopulated )
845840 {
846- // Manual use of IDictionaryEnumerator instead of foreach to avoid DictionaryEntry box allocations.
847- IDictionaryEnumerator e = typeData . GetEnumerator ( ) ;
848- while ( e . MoveNext ( ) )
849- {
850- DictionaryEntry de = e . Entry ;
851- Type type = ( Type ) de . Key ;
852- if ( type . Module == module && ( ( ReflectedTypeData ) de . Value ! ) . IsPopulated )
853- {
854- typeList . Add ( type ) ;
855- }
856- }
841+ typeList . Add ( kvp . Key ) ;
857842 }
858843 }
859844
@@ -898,31 +883,23 @@ public override Type GetReflectionType(
898883 /// </summary>
899884 private ReflectedTypeData ? GetTypeData ( [ DynamicallyAccessedMembers ( DynamicallyAccessedMemberTypes . All ) ] Type type , bool createIfNeeded )
900885 {
901- ReflectedTypeData ? td = null ;
902-
903- if ( _typeData != null )
886+ if ( _typeData . TryGetValue ( type , out ReflectedTypeData ? td ) )
904887 {
905- td = ( ReflectedTypeData ? ) _typeData [ type ] ;
906- if ( td != null )
907- {
908- return td ;
909- }
888+ Debug . Assert ( td != null ) ;
889+ return td ;
910890 }
911891
912- lock ( s_internalSyncObject )
892+ lock ( TypeDescriptor . s_commonSyncObject )
913893 {
914- if ( _typeData != null )
894+ if ( _typeData . TryGetValue ( type , out td ) )
915895 {
916- td = ( ReflectedTypeData ? ) _typeData [ type ] ;
896+ Debug . Assert ( td != null ) ;
897+ return td ;
917898 }
918899
919- if ( td == null && createIfNeeded )
900+ if ( createIfNeeded )
920901 {
921902 td = new ReflectedTypeData ( type ) ;
922- if ( _typeData == null )
923- {
924- _typeData = new Hashtable ( ) ;
925- }
926903 _typeData [ type ] = td ;
927904 }
928905 }
@@ -1010,7 +987,7 @@ internal static Attribute[] ReflectGetAttributes(Type type)
1010987 return attrs ;
1011988 }
1012989
1013- lock ( s_internalSyncObject )
990+ lock ( TypeDescriptor . s_commonSyncObject )
1014991 {
1015992 attrs = ( Attribute [ ] ? ) attributeCache [ type ] ;
1016993 if ( attrs == null )
@@ -1038,7 +1015,7 @@ internal static Attribute[] ReflectGetAttributes(MemberInfo member)
10381015 return attrs ;
10391016 }
10401017
1041- lock ( s_internalSyncObject )
1018+ lock ( TypeDescriptor . s_commonSyncObject )
10421019 {
10431020 attrs = ( Attribute [ ] ? ) attributeCache [ member ] ;
10441021 if ( attrs == null )
@@ -1067,7 +1044,7 @@ private static EventDescriptor[] ReflectGetEvents(
10671044 return events ;
10681045 }
10691046
1070- lock ( s_internalSyncObject )
1047+ lock ( TypeDescriptor . s_commonSyncObject )
10711048 {
10721049 events = ( EventDescriptor [ ] ? ) eventCache [ type ] ;
10731050 if ( events == null )
@@ -1164,7 +1141,7 @@ private static PropertyDescriptor[] ReflectGetExtendedProperties(IExtenderProvid
11641141 ReflectPropertyDescriptor [ ] ? extendedProperties = ( ReflectPropertyDescriptor [ ] ? ) extendedPropertyCache [ providerType ] ;
11651142 if ( extendedProperties == null )
11661143 {
1167- lock ( s_internalSyncObject )
1144+ lock ( TypeDescriptor . s_commonSyncObject )
11681145 {
11691146 extendedProperties = ( ReflectPropertyDescriptor [ ] ? ) extendedPropertyCache [ providerType ] ;
11701147
@@ -1244,7 +1221,7 @@ private static PropertyDescriptor[] ReflectGetProperties(
12441221 return properties ;
12451222 }
12461223
1247- lock ( s_internalSyncObject )
1224+ lock ( TypeDescriptor . s_commonSyncObject )
12481225 {
12491226 properties = ( PropertyDescriptor [ ] ? ) propertyCache [ type ] ;
12501227
0 commit comments