@@ -15,7 +15,7 @@ namespace System.Threading
15
15
public sealed partial class Thread
16
16
{
17
17
[ ThreadStatic ]
18
- private static ApartmentType t_apartmentType ;
18
+ private static sbyte t_apartmentState ; // ApartmentState shifted by ApartmentState.Unknonw to represent Unknown as the default value
19
19
20
20
[ ThreadStatic ]
21
21
private static ComState t_comState ;
@@ -334,14 +334,15 @@ public ApartmentState GetApartmentState()
334
334
return _initialApartmentState ;
335
335
}
336
336
337
- switch ( GetCurrentApartmentType ( ) )
337
+ switch ( GetCurrentApartmentState ( ) )
338
338
{
339
- case ApartmentType . STA :
339
+ case ApartmentState . STA :
340
340
return ApartmentState . STA ;
341
- case ApartmentType . MTA :
341
+ case ApartmentState . MTA :
342
342
return ApartmentState . MTA ;
343
343
default :
344
- return ApartmentState . Unknown ;
344
+ // If COM is uninitialized on the current thread, it is assumed to be implicit MTA.
345
+ return ApartmentState . MTA ;
345
346
}
346
347
}
347
348
@@ -374,14 +375,15 @@ private bool SetApartmentStateUnchecked(ApartmentState state, bool throwOnError)
374
375
}
375
376
else
376
377
{
378
+ // Compat: Setting ApartmentState to Unknown uninitializes COM
377
379
UninitializeCom ( ) ;
378
380
}
379
381
}
380
382
381
383
// Clear the cache and check whether new state matches the desired state
382
- t_apartmentType = ApartmentType . Unknown ;
384
+ t_apartmentState = 0 ;
383
385
384
- retState = GetApartmentState ( ) ;
386
+ retState = GetCurrentApartmentState ( ) ;
385
387
}
386
388
387
389
if ( retState != state )
@@ -527,49 +529,53 @@ internal static void CheckForPendingInterrupt()
527
529
}
528
530
529
531
internal static bool ReentrantWaitsEnabled =>
530
- GetCurrentApartmentType ( ) == ApartmentType . STA ;
532
+ GetCurrentApartmentState ( ) == ApartmentState . STA ;
531
533
532
- internal static ApartmentType GetCurrentApartmentType ( )
534
+ internal static ApartmentState GetCurrentApartmentState ( )
533
535
{
534
- ApartmentType currentThreadType = t_apartmentType ;
535
- if ( currentThreadType != ApartmentType . Unknown )
536
- return currentThreadType ;
536
+ sbyte current = t_apartmentState ;
537
+ if ( current != 0 )
538
+ return ( ApartmentState ) ( current + ( sbyte ) ApartmentState . Unknown ) ;
537
539
538
540
Interop . APTTYPE aptType ;
539
541
Interop . APTTYPEQUALIFIER aptTypeQualifier ;
540
542
int result = Interop . Ole32 . CoGetApartmentType ( out aptType , out aptTypeQualifier ) ;
541
543
542
- ApartmentType type = ApartmentType . Unknown ;
544
+ ApartmentState state = ApartmentState . Unknown ;
543
545
544
546
switch ( result )
545
547
{
546
548
case HResults . CO_E_NOTINITIALIZED :
547
- type = ApartmentType . None ;
549
+ Debug . Fail ( "COM is not initialized" ) ;
550
+ state = ApartmentState . Unknown ;
548
551
break ;
549
552
550
553
case HResults . S_OK :
551
554
switch ( aptType )
552
555
{
553
556
case Interop . APTTYPE . APTTYPE_STA :
554
557
case Interop . APTTYPE . APTTYPE_MAINSTA :
555
- type = ApartmentType . STA ;
558
+ state = ApartmentState . STA ;
556
559
break ;
557
560
558
561
case Interop . APTTYPE . APTTYPE_MTA :
559
- type = ApartmentType . MTA ;
562
+ state = ApartmentState . MTA ;
560
563
break ;
561
564
562
565
case Interop . APTTYPE . APTTYPE_NA :
563
566
switch ( aptTypeQualifier )
564
567
{
565
568
case Interop . APTTYPEQUALIFIER . APTTYPEQUALIFIER_NA_ON_MTA :
569
+ state = ApartmentState . MTA ;
570
+ break ;
571
+
566
572
case Interop . APTTYPEQUALIFIER . APTTYPEQUALIFIER_NA_ON_IMPLICIT_MTA :
567
- type = ApartmentType . MTA ;
573
+ state = ApartmentState . Unknown ;
568
574
break ;
569
575
570
576
case Interop . APTTYPEQUALIFIER . APTTYPEQUALIFIER_NA_ON_STA :
571
577
case Interop . APTTYPEQUALIFIER . APTTYPEQUALIFIER_NA_ON_MAINSTA :
572
- type = ApartmentType . STA ;
578
+ state = ApartmentState . STA ;
573
579
break ;
574
580
575
581
default :
@@ -581,21 +587,13 @@ internal static ApartmentType GetCurrentApartmentType()
581
587
break ;
582
588
583
589
default :
584
- Debug . Fail ( "bad return from CoGetApartmentType " ) ;
590
+ Debug . Fail ( "bad return from CoGetApartmentState " ) ;
585
591
break ;
586
592
}
587
593
588
- if ( type != ApartmentType . Unknown )
589
- t_apartmentType = type ;
590
- return type ;
591
- }
592
-
593
- internal enum ApartmentType : byte
594
- {
595
- Unknown = 0 ,
596
- None ,
597
- STA ,
598
- MTA
594
+ if ( state != ApartmentState . Unknown )
595
+ t_apartmentState = ( sbyte ) ( state - ApartmentState . Unknown ) ;
596
+ return state ;
599
597
}
600
598
601
599
[ Flags ]
0 commit comments