22// The .NET Foundation licenses this file to you under the MIT license.
33// See the LICENSE file in the project root for more information.
44
5- using System . Collections . Generic ;
5+ using System . Collections . Concurrent ;
66using System . IO ;
77using System . Reflection . Metadata ;
88using System . Reflection . Metadata . Ecma335 ;
@@ -12,14 +12,14 @@ namespace System.Diagnostics
1212{
1313 internal class StackTraceSymbols : IDisposable
1414 {
15- private readonly Dictionary < IntPtr , MetadataReaderProvider > _metadataCache ;
15+ private readonly ConcurrentDictionary < IntPtr , MetadataReaderProvider > _metadataCache ;
1616
1717 /// <summary>
1818 /// Create an instance of this class.
1919 /// </summary>
2020 public StackTraceSymbols ( )
2121 {
22- _metadataCache = new Dictionary < IntPtr , MetadataReaderProvider > ( ) ;
22+ _metadataCache = new ConcurrentDictionary < IntPtr , MetadataReaderProvider > ( ) ;
2323 }
2424
2525 /// <summary>
@@ -29,7 +29,7 @@ void IDisposable.Dispose()
2929 {
3030 foreach ( MetadataReaderProvider provider in _metadataCache . Values )
3131 {
32- provider . Dispose ( ) ;
32+ provider ? . Dispose ( ) ;
3333 }
3434
3535 _metadataCache . Clear ( ) ;
@@ -123,20 +123,21 @@ private unsafe MetadataReader TryGetReader(string assemblyPath, IntPtr loadedPeA
123123 MetadataReaderProvider provider ;
124124 if ( _metadataCache . TryGetValue ( cacheKey , out provider ) )
125125 {
126- return provider . GetMetadataReader ( ) ;
126+ return provider ? . GetMetadataReader ( ) ;
127127 }
128128
129129 provider = ( inMemoryPdbAddress != IntPtr . Zero ) ?
130130 TryOpenReaderForInMemoryPdb ( inMemoryPdbAddress , inMemoryPdbSize ) :
131131 TryOpenReaderFromAssemblyFile ( assemblyPath , loadedPeAddress , loadedPeSize ) ;
132132
133+ // This may fail as another thread might have beaten us to it, but it doesn't matter
134+ _metadataCache . TryAdd ( cacheKey , provider ) ;
135+
133136 if ( provider == null )
134137 {
135138 return null ;
136139 }
137140
138- _metadataCache . Add ( cacheKey , provider ) ;
139-
140141 // The reader has already been open, so this doesn't throw:
141142 return provider . GetMetadataReader ( ) ;
142143 }
0 commit comments