55#if FEATURE_COM
66
77using System ;
8- using System . Collections ;
8+ using System . Collections . Concurrent ;
99using System . Collections . Generic ;
10+ using System . Globalization ;
1011using System . Runtime . InteropServices . ComTypes ;
1112using System . Threading ;
1213
@@ -15,14 +16,8 @@ namespace Microsoft.Scripting.ComInterop {
1516 public class ComTypeDesc : ComTypeLibMemberDesc {
1617 private readonly string _typeName ;
1718 private readonly string _documentation ;
18- //Hashtable is threadsafe for multiple readers single writer.
19- //Enumerating and writing is mutually exclusive so require locking.
20- private Hashtable _funcs ;
21- private Hashtable _puts ;
22- private Hashtable _putRefs ;
2319 private ComMethodDesc _getItem ;
2420 private ComMethodDesc _setItem ;
25- private Dictionary < string , ComEventDesc > _events ;
2621 private static readonly Dictionary < string , ComEventDesc > _EmptyEventsDict = new ( ) ;
2722
2823 internal ComTypeDesc ( ITypeInfo typeInfo , ComType memberType , ComTypeLibDesc typeLibDesc ) : base ( memberType ) {
@@ -51,122 +46,101 @@ internal static ComTypeDesc FromITypeInfo(ITypeInfo typeInfo, TYPEATTR typeAttr)
5146
5247 internal static ComTypeDesc CreateEmptyTypeDesc ( ) {
5348 ComTypeDesc typeDesc = new ComTypeDesc ( null , ComType . Interface , null ) ;
54- typeDesc . _funcs = new Hashtable ( ) ;
55- typeDesc . _puts = new Hashtable ( ) ;
56- typeDesc . _putRefs = new Hashtable ( ) ;
57- typeDesc . _events = _EmptyEventsDict ;
49+ typeDesc . Funcs = new ConcurrentDictionary < string , ComMethodDesc > ( ) ;
50+ typeDesc . Puts = new ConcurrentDictionary < string , ComMethodDesc > ( ) ;
51+ typeDesc . PutRefs = new ConcurrentDictionary < string , ComMethodDesc > ( ) ;
52+ typeDesc . Events = _EmptyEventsDict ;
5853
5954 return typeDesc ;
6055 }
6156
62- internal static Dictionary < string , ComEventDesc > EmptyEvents {
63- get { return _EmptyEventsDict ; }
64- }
57+ internal static Dictionary < string , ComEventDesc > EmptyEvents => _EmptyEventsDict ;
6558
66- internal Hashtable Funcs {
67- get { return _funcs ; }
68- set { _funcs = value ; }
69- }
59+ internal ConcurrentDictionary < string , ComMethodDesc > Funcs { get ; set ; }
7060
71- internal Hashtable Puts {
72- get { return _puts ; }
73- set { _puts = value ; }
74- }
61+ internal ConcurrentDictionary < string , ComMethodDesc > Puts { get ; set ; }
7562
76- internal Hashtable PutRefs {
77- set { _putRefs = value ; }
78- }
63+ internal ConcurrentDictionary < string , ComMethodDesc > PutRefs { get ; set ; }
7964
80- internal Dictionary < string , ComEventDesc > Events {
81- get { return _events ; }
82- set { _events = value ; }
83- }
65+ internal Dictionary < string , ComEventDesc > Events { get ; set ; }
8466
8567 internal bool TryGetFunc ( string name , out ComMethodDesc method ) {
86- name = name . ToUpper ( System . Globalization . CultureInfo . InvariantCulture ) ;
87- if ( _funcs . ContainsKey ( name ) ) {
88- method = _funcs [ name ] as ComMethodDesc ;
68+ name = name . ToUpper ( CultureInfo . InvariantCulture ) ;
69+ if ( Funcs . TryGetValue ( name , out method ) ) {
8970 return true ;
9071 }
91- method = null ;
72+
9273 return false ;
9374 }
9475
9576 internal void AddFunc ( string name , ComMethodDesc method ) {
96- name = name . ToUpper ( System . Globalization . CultureInfo . InvariantCulture ) ;
97- lock ( _funcs ) {
98- _funcs [ name ] = method ;
99- }
77+ name = name . ToUpper ( CultureInfo . InvariantCulture ) ;
78+ Funcs [ name ] = method ;
10079 }
10180
10281 internal bool TryGetPut ( string name , out ComMethodDesc method ) {
103- name = name . ToUpper ( System . Globalization . CultureInfo . InvariantCulture ) ;
104- if ( _puts . ContainsKey ( name ) ) {
105- method = _puts [ name ] as ComMethodDesc ;
82+ name = name . ToUpper ( CultureInfo . InvariantCulture ) ;
83+ if ( Puts . TryGetValue ( name , out method ) ) {
10684 return true ;
10785 }
108- method = null ;
86+
10987 return false ;
11088 }
11189
11290 internal void AddPut ( string name , ComMethodDesc method ) {
113- name = name . ToUpper ( System . Globalization . CultureInfo . InvariantCulture ) ;
114- lock ( _puts ) {
115- _puts [ name ] = method ;
116- }
91+ name = name . ToUpper ( CultureInfo . InvariantCulture ) ;
92+ Puts [ name ] = method ;
11793 }
11894
11995 internal bool TryGetPutRef ( string name , out ComMethodDesc method ) {
120- name = name . ToUpper ( System . Globalization . CultureInfo . InvariantCulture ) ;
121- if ( _putRefs . ContainsKey ( name ) ) {
122- method = _putRefs [ name ] as ComMethodDesc ;
96+ name = name . ToUpper ( CultureInfo . InvariantCulture ) ;
97+ if ( PutRefs . TryGetValue ( name , out method ) ) {
12398 return true ;
12499 }
125- method = null ;
100+
126101 return false ;
127102 }
128103 internal void AddPutRef ( string name , ComMethodDesc method ) {
129- name = name . ToUpper ( System . Globalization . CultureInfo . InvariantCulture ) ;
130- lock ( _putRefs ) {
131- _putRefs [ name ] = method ;
132- }
104+ name = name . ToUpper ( CultureInfo . InvariantCulture ) ;
105+ PutRefs [ name ] = method ;
106+
133107 }
134108
135109 internal bool TryGetEvent ( string name , out ComEventDesc @event ) {
136- name = name . ToUpper ( System . Globalization . CultureInfo . InvariantCulture ) ;
137- return _events . TryGetValue ( name , out @event ) ;
110+ name = name . ToUpper ( CultureInfo . InvariantCulture ) ;
111+ return Events . TryGetValue ( name , out @event ) ;
138112 }
139113
140114 internal string [ ] GetMemberNames ( bool dataOnly ) {
141115 var names = new Dictionary < string , object > ( ) ;
142116
143- lock ( _funcs ) {
144- foreach ( ComMethodDesc func in _funcs . Values ) {
117+ lock ( Funcs ) {
118+ foreach ( ComMethodDesc func in Funcs . Values ) {
145119 if ( ! dataOnly || func . IsDataMember ) {
146120 names . Add ( func . Name , null ) ;
147121 }
148122 }
149123 }
150124
151125 if ( ! dataOnly ) {
152- lock ( _puts ) {
153- foreach ( ComMethodDesc func in _puts . Values ) {
126+ lock ( Puts ) {
127+ foreach ( ComMethodDesc func in Puts . Values ) {
154128 if ( ! names . ContainsKey ( func . Name ) ) {
155129 names . Add ( func . Name , null ) ;
156130 }
157131 }
158132 }
159133
160- lock ( _putRefs ) {
161- foreach ( ComMethodDesc func in _putRefs . Values ) {
134+ lock ( PutRefs ) {
135+ foreach ( ComMethodDesc func in PutRefs . Values ) {
162136 if ( ! names . ContainsKey ( func . Name ) ) {
163137 names . Add ( func . Name , null ) ;
164138 }
165139 }
166140 }
167141
168- if ( _events is not null && _events . Count > 0 ) {
169- foreach ( string name in _events . Keys ) {
142+ if ( Events is not null && Events . Count > 0 ) {
143+ foreach ( string name in Events . Keys ) {
170144 if ( ! names . ContainsKey ( name ) ) {
171145 names . Add ( name , null ) ;
172146 }
@@ -180,30 +154,22 @@ internal string[] GetMemberNames(bool dataOnly) {
180154 }
181155
182156 // this property is public - accessed by an AST
183- public string TypeName {
184- get { return _typeName ; }
185- }
157+ public string TypeName => _typeName ;
186158
187- internal string Documentation {
188- get { return _documentation ; }
189- }
159+ internal string Documentation => _documentation ;
190160
191161 // this property is public - accessed by an AST
192162 public ComTypeLibDesc TypeLib { get ; }
193163
194164 internal Guid Guid { get ; set ; }
195165
196- internal ComMethodDesc GetItem {
197- get { return _getItem ; }
198- }
166+ internal ComMethodDesc GetItem => _getItem ;
199167
200168 internal void EnsureGetItem ( ComMethodDesc candidate ) {
201169 Interlocked . CompareExchange ( ref _getItem , candidate , null ) ;
202170 }
203171
204- internal ComMethodDesc SetItem {
205- get { return _setItem ; }
206- }
172+ internal ComMethodDesc SetItem => _setItem ;
207173
208174 internal void EnsureSetItem ( ComMethodDesc candidate ) {
209175 Interlocked . CompareExchange ( ref _setItem , candidate , null ) ;
0 commit comments