3
3
4
4
using System . Collections ;
5
5
using System . Collections . Generic ;
6
+ using System . Collections . Concurrent ;
6
7
using System . ComponentModel . Design ;
7
8
using System . Diagnostics ;
8
9
using System . Diagnostics . CodeAnalysis ;
@@ -22,10 +23,8 @@ namespace System.ComponentModel
22
23
/// </summary>
23
24
internal sealed partial class ReflectTypeDescriptionProvider : TypeDescriptionProvider
24
25
{
25
- // Hastable of Type -> ReflectedTypeData. ReflectedTypeData contains all
26
- // of the type information we have gathered for a given type.
27
- //
28
- private Hashtable ? _typeData ;
26
+ // ReflectedTypeData contains all of the type information we have gathered for a given type.
27
+ private readonly ConcurrentDictionary < Type , ReflectedTypeData > _typeData = new ConcurrentDictionary < Type , ReflectedTypeData > ( ) ;
29
28
30
29
// This is the signature we look for when creating types that are generic, but
31
30
// want to know what type they are dealing with. Enums are a good example of this;
@@ -91,8 +90,6 @@ private static Type[] InitializeSkipInterfaceAttributeList()
91
90
92
91
internal static Guid ExtenderProviderKey { get ; } = Guid . NewGuid ( ) ;
93
92
94
-
95
- private static readonly object s_internalSyncObject = new object ( ) ;
96
93
/// <summary>
97
94
/// Creates a new ReflectTypeDescriptionProvider. The type is the
98
95
/// type we will obtain type information for.
@@ -243,7 +240,7 @@ internal static void AddEditorTable(Type editorBaseType, Hashtable table)
243
240
244
241
Debug . Assert ( table != null , "COMPAT: Editor table should not be null" ) ; // don't throw; RTM didn't so we can't do it either.
245
242
246
- lock ( s_internalSyncObject )
243
+ lock ( TypeDescriptor . s_commonSyncObject )
247
244
{
248
245
Hashtable editorTables = EditorTables ;
249
246
if ( ! editorTables . ContainsKey ( editorBaseType ) )
@@ -298,7 +295,6 @@ internal static void AddEditorTable(Type editorBaseType, Hashtable table)
298
295
return obj ?? Activator . CreateInstance ( objectType , args ) ;
299
296
}
300
297
301
-
302
298
/// <summary>
303
299
/// Helper method to create editors and type converters. This checks to see if the
304
300
/// type implements a Type constructor, and if it does it invokes that ctor.
@@ -429,7 +425,7 @@ internal TypeConverter GetConverter([DynamicallyAccessedMembers(DynamicallyAcces
429
425
//
430
426
if ( table == null )
431
427
{
432
- lock ( s_internalSyncObject )
428
+ lock ( TypeDescriptor . s_commonSyncObject )
433
429
{
434
430
table = editorTables [ editorBaseType ] ;
435
431
if ( table == null )
@@ -837,22 +833,11 @@ internal Type[] GetPopulatedTypes(Module module)
837
833
{
838
834
List < Type > typeList = new List < Type > ( ) ;
839
835
840
- lock ( s_internalSyncObject )
836
+ foreach ( KeyValuePair < Type , ReflectedTypeData > kvp in _typeData )
841
837
{
842
- Hashtable ? typeData = _typeData ;
843
- if ( typeData != null )
838
+ if ( kvp . Key . Module == module && kvp . Value ! . IsPopulated )
844
839
{
845
- // Manual use of IDictionaryEnumerator instead of foreach to avoid DictionaryEntry box allocations.
846
- IDictionaryEnumerator e = typeData . GetEnumerator ( ) ;
847
- while ( e . MoveNext ( ) )
848
- {
849
- DictionaryEntry de = e . Entry ;
850
- Type type = ( Type ) de . Key ;
851
- if ( type . Module == module && ( ( ReflectedTypeData ) de . Value ! ) . IsPopulated )
852
- {
853
- typeList . Add ( type ) ;
854
- }
855
- }
840
+ typeList . Add ( kvp . Key ) ;
856
841
}
857
842
}
858
843
@@ -897,28 +882,23 @@ public override Type GetReflectionType(
897
882
/// </summary>
898
883
private ReflectedTypeData ? GetTypeData ( [ DynamicallyAccessedMembers ( DynamicallyAccessedMemberTypes . All ) ] Type type , bool createIfNeeded )
899
884
{
900
- ReflectedTypeData ? td = null ;
901
-
902
- if ( _typeData != null )
885
+ if ( _typeData . TryGetValue ( type , out ReflectedTypeData ? td ) )
903
886
{
904
- td = ( ReflectedTypeData ? ) _typeData [ type ] ;
905
- if ( td != null )
906
- {
907
- return td ;
908
- }
887
+ Debug . Assert ( td != null ) ;
888
+ return td ;
909
889
}
910
890
911
- lock ( s_internalSyncObject )
891
+ lock ( TypeDescriptor . s_commonSyncObject )
912
892
{
913
- if ( _typeData != null )
893
+ if ( _typeData . TryGetValue ( type , out td ) )
914
894
{
915
- td = ( ReflectedTypeData ? ) _typeData [ type ] ;
895
+ Debug . Assert ( td != null ) ;
896
+ return td ;
916
897
}
917
898
918
- if ( td == null && createIfNeeded )
899
+ if ( createIfNeeded )
919
900
{
920
901
td = new ReflectedTypeData ( type ) ;
921
- _typeData ??= new Hashtable ( ) ;
922
902
_typeData [ type ] = td ;
923
903
}
924
904
}
@@ -1006,7 +986,7 @@ internal static Attribute[] ReflectGetAttributes(Type type)
1006
986
return attrs ;
1007
987
}
1008
988
1009
- lock ( s_internalSyncObject )
989
+ lock ( TypeDescriptor . s_commonSyncObject )
1010
990
{
1011
991
attrs = ( Attribute [ ] ? ) attributeCache [ type ] ;
1012
992
if ( attrs == null )
@@ -1034,7 +1014,7 @@ internal static Attribute[] ReflectGetAttributes(MemberInfo member)
1034
1014
return attrs ;
1035
1015
}
1036
1016
1037
- lock ( s_internalSyncObject )
1017
+ lock ( TypeDescriptor . s_commonSyncObject )
1038
1018
{
1039
1019
attrs = ( Attribute [ ] ? ) attributeCache [ member ] ;
1040
1020
if ( attrs == null )
@@ -1063,7 +1043,7 @@ private static EventDescriptor[] ReflectGetEvents(
1063
1043
return events ;
1064
1044
}
1065
1045
1066
- lock ( s_internalSyncObject )
1046
+ lock ( TypeDescriptor . s_commonSyncObject )
1067
1047
{
1068
1048
events = ( EventDescriptor [ ] ? ) eventCache [ type ] ;
1069
1049
if ( events == null )
@@ -1160,7 +1140,7 @@ private static PropertyDescriptor[] ReflectGetExtendedProperties(IExtenderProvid
1160
1140
ReflectPropertyDescriptor [ ] ? extendedProperties = ( ReflectPropertyDescriptor [ ] ? ) extendedPropertyCache [ providerType ] ;
1161
1141
if ( extendedProperties == null )
1162
1142
{
1163
- lock ( s_internalSyncObject )
1143
+ lock ( TypeDescriptor . s_commonSyncObject )
1164
1144
{
1165
1145
extendedProperties = ( ReflectPropertyDescriptor [ ] ? ) extendedPropertyCache [ providerType ] ;
1166
1146
@@ -1240,7 +1220,7 @@ private static PropertyDescriptor[] ReflectGetProperties(
1240
1220
return properties ;
1241
1221
}
1242
1222
1243
- lock ( s_internalSyncObject )
1223
+ lock ( TypeDescriptor . s_commonSyncObject )
1244
1224
{
1245
1225
properties = ( PropertyDescriptor [ ] ? ) propertyCache [ type ] ;
1246
1226
0 commit comments