invalidApartmentStateChange MDA
Notitie
Dit artikel is specifiek voor .NET Framework. Dit geldt niet voor nieuwere implementaties van .NET, waaronder .NET 6 en nieuwere versies.
De invalidApartmentStateChange
beheerde foutopsporingsassistent (MDS) wordt geactiveerd door een van de twee problemen:
Er wordt geprobeerd de com-appartementstatus te wijzigen van een thread die al door COM is geïnitialiseerd naar een andere appartementsstatus.
De COM-appartementsstatus van een thread verandert onverwacht.
Symptomen
De com-appartementstatus van een thread is niet wat is aangevraagd. Dit kan ertoe leiden dat proxy's worden gebruikt voor COM-onderdelen die een threadingmodel hebben dat verschilt van het huidige model. Dit kan er op zijn beurt toe leiden dat er een InvalidCastException wordt gegenereerd bij het aanroepen van het COM-object via interfaces die niet zijn ingesteld voor marshalling tussen appartementen.
De com-appartementsstatus van de thread is anders dan verwacht. Dit kan leiden tot een COMException HRESULT van RPC_E_WRONG_THREAD en een InvalidCastException bij het maken van aanroepen op een Runtime Callable Wrapper (RCW). Dit kan er ook toe leiden dat bepaalde COM-onderdelen met één thread tegelijkertijd worden geopend door meerdere threads, wat kan leiden tot beschadiging of gegevensverlies.
Oorzaak
De thread werd eerder geïnitialiseerd naar een andere COM-appartementsstatus. Houd er rekening mee dat de appartementsstatus van een thread expliciet of impliciet kan worden ingesteld. De expliciete bewerkingen omvatten de Thread.ApartmentState eigenschap en de SetApartmentState en TrySetApartmentState methoden. Een thread die met de Start methode wordt gemaakt, wordt impliciet ingesteld op MTA tenzij SetApartmentState deze wordt aangeroepen voordat de thread wordt gestart. De hoofdthread van de toepassing wordt ook impliciet geïnitialiseerd, MTA tenzij het STAThreadAttribute kenmerk is opgegeven in de hoofdmethode.
De
CoUninitialize
methode (of deCoInitializeEx
methode) met een ander gelijktijdigheidsmodel wordt aangeroepen op de thread.
Oplossing
Stel de appartementsstatus van de thread in voordat deze wordt uitgevoerd, of pas het STAThreadAttribute kenmerk of het MTAThreadAttribute kenmerk toe op de hoofdmethode van de toepassing.
Voor de tweede oorzaak, in het ideale geval, moet de code die de CoUninitialize
methode aanroept, worden gewijzigd om de aanroep te vertragen totdat de thread bijna wordt beëindigd en er geen RCW's en de onderliggende COM-onderdelen die nog in gebruik zijn door de thread. Als het echter niet mogelijk is om de code te wijzigen die de CoUninitialize
methode aanroept, moeten er geen RCW's worden gebruikt vanuit threads die op deze manier niet zijn geïnitialiseerd.
Effect op de runtime
Deze MDA heeft geen effect op de CLR.
Uitvoer
De com-appartementstatus van de huidige thread en de status dat de code probeerde toe te passen.
Configuratie
<mdaConfig>
<assistants>
<invalidApartmentStateChange />
</assistants>
</mdaConfig>
Opmerking
In het volgende codevoorbeeld ziet u een situatie waarin deze MDA kan worden geactiveerd.
using System.Threading;
namespace ApartmentStateMDA
{
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
}
}
}