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 ;
@@ -23,10 +24,8 @@ namespace System.ComponentModel
23
24
/// </summary>
24
25
internal sealed partial class ReflectTypeDescriptionProvider : TypeDescriptionProvider
25
26
{
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 > ( ) ;
30
29
31
30
// This is the signature we look for when creating types that are generic, but
32
31
// 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
81
80
82
81
internal static Guid ExtenderProviderKey { get ; } = Guid . NewGuid ( ) ;
83
82
84
-
85
- private static readonly object s_internalSyncObject = new object ( ) ;
86
83
/// <summary>
87
84
/// Creates a new ReflectTypeDescriptionProvider. The type is the
88
85
/// type we will obtain type information for.
@@ -234,7 +231,7 @@ internal static void AddEditorTable(Type editorBaseType, Hashtable table)
234
231
// don't throw; RTM didn't so we can't do it either.
235
232
}
236
233
237
- lock ( s_internalSyncObject )
234
+ lock ( TypeDescriptor . s_commonSyncObject )
238
235
{
239
236
Hashtable editorTables = EditorTables ;
240
237
if ( ! editorTables . ContainsKey ( editorBaseType ) )
@@ -289,7 +286,6 @@ internal static void AddEditorTable(Type editorBaseType, Hashtable table)
289
286
return obj ?? Activator . CreateInstance ( objectType , args ) ;
290
287
}
291
288
292
-
293
289
/// <summary>
294
290
/// Helper method to create editors and type converters. This checks to see if the
295
291
/// type implements a Type constructor, and if it does it invokes that ctor.
@@ -421,7 +417,7 @@ internal TypeConverter GetConverter([DynamicallyAccessedMembers(DynamicallyAcces
421
417
//
422
418
if ( table == null )
423
419
{
424
- lock ( s_internalSyncObject )
420
+ lock ( TypeDescriptor . s_commonSyncObject )
425
421
{
426
422
table = editorTables [ editorBaseType ] ;
427
423
if ( table == null )
@@ -838,22 +834,11 @@ internal Type[] GetPopulatedTypes(Module module)
838
834
{
839
835
List < Type > typeList = new List < Type > ( ) ;
840
836
841
- lock ( s_internalSyncObject )
837
+ foreach ( KeyValuePair < Type , ReflectedTypeData > kvp in _typeData )
842
838
{
843
- Hashtable ? typeData = _typeData ;
844
- if ( typeData != null )
839
+ if ( kvp . Key . Module == module && kvp . Value ! . IsPopulated )
845
840
{
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 ) ;
857
842
}
858
843
}
859
844
@@ -898,31 +883,23 @@ public override Type GetReflectionType(
898
883
/// </summary>
899
884
private ReflectedTypeData ? GetTypeData ( [ DynamicallyAccessedMembers ( DynamicallyAccessedMemberTypes . All ) ] Type type , bool createIfNeeded )
900
885
{
901
- ReflectedTypeData ? td = null ;
902
-
903
- if ( _typeData != null )
886
+ if ( _typeData . TryGetValue ( type , out ReflectedTypeData ? td ) )
904
887
{
905
- td = ( ReflectedTypeData ? ) _typeData [ type ] ;
906
- if ( td != null )
907
- {
908
- return td ;
909
- }
888
+ Debug . Assert ( td != null ) ;
889
+ return td ;
910
890
}
911
891
912
- lock ( s_internalSyncObject )
892
+ lock ( TypeDescriptor . s_commonSyncObject )
913
893
{
914
- if ( _typeData != null )
894
+ if ( _typeData . TryGetValue ( type , out td ) )
915
895
{
916
- td = ( ReflectedTypeData ? ) _typeData [ type ] ;
896
+ Debug . Assert ( td != null ) ;
897
+ return td ;
917
898
}
918
899
919
- if ( td == null && createIfNeeded )
900
+ if ( createIfNeeded )
920
901
{
921
902
td = new ReflectedTypeData ( type ) ;
922
- if ( _typeData == null )
923
- {
924
- _typeData = new Hashtable ( ) ;
925
- }
926
903
_typeData [ type ] = td ;
927
904
}
928
905
}
@@ -1010,7 +987,7 @@ internal static Attribute[] ReflectGetAttributes(Type type)
1010
987
return attrs ;
1011
988
}
1012
989
1013
- lock ( s_internalSyncObject )
990
+ lock ( TypeDescriptor . s_commonSyncObject )
1014
991
{
1015
992
attrs = ( Attribute [ ] ? ) attributeCache [ type ] ;
1016
993
if ( attrs == null )
@@ -1038,7 +1015,7 @@ internal static Attribute[] ReflectGetAttributes(MemberInfo member)
1038
1015
return attrs ;
1039
1016
}
1040
1017
1041
- lock ( s_internalSyncObject )
1018
+ lock ( TypeDescriptor . s_commonSyncObject )
1042
1019
{
1043
1020
attrs = ( Attribute [ ] ? ) attributeCache [ member ] ;
1044
1021
if ( attrs == null )
@@ -1067,7 +1044,7 @@ private static EventDescriptor[] ReflectGetEvents(
1067
1044
return events ;
1068
1045
}
1069
1046
1070
- lock ( s_internalSyncObject )
1047
+ lock ( TypeDescriptor . s_commonSyncObject )
1071
1048
{
1072
1049
events = ( EventDescriptor [ ] ? ) eventCache [ type ] ;
1073
1050
if ( events == null )
@@ -1164,7 +1141,7 @@ private static PropertyDescriptor[] ReflectGetExtendedProperties(IExtenderProvid
1164
1141
ReflectPropertyDescriptor [ ] ? extendedProperties = ( ReflectPropertyDescriptor [ ] ? ) extendedPropertyCache [ providerType ] ;
1165
1142
if ( extendedProperties == null )
1166
1143
{
1167
- lock ( s_internalSyncObject )
1144
+ lock ( TypeDescriptor . s_commonSyncObject )
1168
1145
{
1169
1146
extendedProperties = ( ReflectPropertyDescriptor [ ] ? ) extendedPropertyCache [ providerType ] ;
1170
1147
@@ -1244,7 +1221,7 @@ private static PropertyDescriptor[] ReflectGetProperties(
1244
1221
return properties ;
1245
1222
}
1246
1223
1247
- lock ( s_internalSyncObject )
1224
+ lock ( TypeDescriptor . s_commonSyncObject )
1248
1225
{
1249
1226
properties = ( PropertyDescriptor [ ] ? ) propertyCache [ type ] ;
1250
1227
0 commit comments