1
1
// Licensed to the .NET Foundation under one or more agreements.
2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
+ using System . Collections . Concurrent ;
4
5
using System . ComponentModel ;
5
6
using System . Runtime . ExceptionServices ;
6
7
using Microsoft . Office ;
@@ -22,9 +23,7 @@ internal abstract unsafe partial class ThreadContext : MarshalByRefObject, IHand
22
23
private bool _inThreadException ;
23
24
private bool _filterSnapshotValid ;
24
25
25
- private static readonly Dictionary < uint , ThreadContext > s_contextHash = [ ] ;
26
-
27
- private static readonly Lock s_lock = new ( ) ;
26
+ private static readonly ConcurrentDictionary < uint , ThreadContext > s_contextHash = [ ] ;
28
27
private readonly Lock _marshallingControlLock = new ( ) ;
29
28
30
29
private static int s_totalMessageLoopCount ;
@@ -87,11 +86,7 @@ protected ThreadContext()
87
86
_id = PInvokeCore . GetCurrentThreadId ( ) ;
88
87
_messageLoopCount = 0 ;
89
88
t_currentThreadContext = this ;
90
-
91
- lock ( s_lock )
92
- {
93
- s_contextHash [ _id ] = this ;
94
- }
89
+ s_contextHash [ _id ] = this ;
95
90
}
96
91
97
92
public ApplicationContext ? ApplicationContext { get ; private set ; }
@@ -316,10 +311,7 @@ private void DisposeInternal(bool disposing)
316
311
}
317
312
finally
318
313
{
319
- lock ( s_lock )
320
- {
321
- s_contextHash . Remove ( _id ) ;
322
- }
314
+ s_contextHash . Remove ( _id , out _ ) ;
323
315
324
316
if ( t_currentThreadContext == this )
325
317
{
@@ -439,27 +431,17 @@ protected virtual void EndModalMessageLoop() { }
439
431
/// <summary>
440
432
/// Exits the program by disposing of all thread contexts and message loops.
441
433
/// </summary>
442
- internal static void ExitApplication ( ) => ExitCommon ( disposing : true ) ;
443
-
444
- private static void ExitCommon ( bool disposing )
434
+ internal static void ExitApplication ( )
445
435
{
446
- lock ( s_lock )
436
+ foreach ( ( _ , var threadContext ) in s_contextHash )
447
437
{
448
- if ( s_contextHash is not null )
438
+ if ( threadContext . ApplicationContext is ApplicationContext applicationContext )
449
439
{
450
- ThreadContext [ ] contexts = new ThreadContext [ s_contextHash . Values . Count ] ;
451
- s_contextHash . Values . CopyTo ( contexts , 0 ) ;
452
- for ( int i = 0 ; i < contexts . Length ; ++ i )
453
- {
454
- if ( contexts [ i ] . ApplicationContext is ApplicationContext context )
455
- {
456
- context . ExitThread ( ) ;
457
- }
458
- else
459
- {
460
- contexts [ i ] . Dispose ( disposing ) ;
461
- }
462
- }
440
+ applicationContext . ExitThread ( ) ;
441
+ }
442
+ else
443
+ {
444
+ threadContext . Dispose ( disposing : true ) ;
463
445
}
464
446
}
465
447
}
@@ -517,14 +499,8 @@ private static ThreadContext Create()
517
499
518
500
if ( id == PInvokeCore . GetCurrentThreadId ( ) )
519
501
{
520
- lock ( s_lock )
521
- {
522
- // Check again inside the lock as another thread may have added it
523
- if ( ! s_contextHash . TryGetValue ( id , out context ) )
524
- {
525
- context = Create ( ) ;
526
- }
527
- }
502
+ context = Create ( ) ;
503
+ Debug . Assert ( context . _id == id ) ;
528
504
}
529
505
530
506
return context ;
0 commit comments