MDA invalidApartmentStateChange
Nota
Questo articolo è specifico per .NET Framework. Non si applica alle implementazioni più recenti di .NET, incluse .NET 6 e versioni successive.
L'assistente al debug gestito invalidApartmentStateChange
viene attivato quando si verificano due problemi diversi:
Viene effettuato un tentativo di modificare lo stato di apartment COM di un thread che è già stato inizializzato da COM in uno stato di apartment diverso.
Lo stato di apartment COM di un thread cambia in modo imprevisto.
Sintomi
Lo stato di apartment COM di un thread è diverso da quello richiesto. Questo problema può causare l'uso di proxy per componenti COM associati a un modello di threading diverso da quello corrente. Questo a sua volta può causare un'eccezione InvalidCastException quando si chiama l'oggetto COM tramite interfacce non configurate per il marshalling tra apartment.
Lo stato di apartment COM del thread è diverso da quello previsto. Questo problema può provocare un'eccezione COMException con valore HRESULT impostato su RPC_E_WRONG_THREAD, nonché un'eccezione InvalidCastException quando si effettuano chiamate in un Runtime Callable Wrapper (RCW). Questo problema può anche far sì che diversi thread accedano contemporaneamente ad alcuni componenti COM a thread singolo, danneggiando i dati o provocandone la perdita.
Causa
Il thread è stato precedentemente inizializzato in uno stato di apartment COM diverso. Si noti che lo stato di apartment di un thread può essere impostato in modo sia esplicito sia implicito. Le operazioni esplicite includono la proprietà Thread.ApartmentState e i metodi SetApartmentState e TrySetApartmentState. Un thread creato con il metodo Start viene impostato in modo implicito su MTA, a meno che SetApartmentState non venga chiamato prima dell'avvio del thread. Anche il thread principale dell'applicazione viene inizializzato in modo implicito in MTA, a meno che nel metodo principale non sia specificato l'attributo STAThreadAttribute.
Nel thread viene chiamato il metodo
CoUninitialize
(o il metodoCoInitializeEx
) con un modello di concorrenza diverso.
Risoluzione
Impostare lo stato di apartment del thread prima dell'avvio dell'esecuzione oppure applicare l'attributo STAThreadAttribute o MTAThreadAttribute al metodo principale dell'applicazione.
Per la seconda causa, idealmente, il codice che chiama il metodo CoUninitialize
deve essere modificato in modo da ritardare la chiamata finché il thread non sta per terminare e non vi sono RCW, né i rispettivi componenti COM sottostanti, ancora in uso da parte del thread. Tuttavia, se non è possibile modificare il codice che chiama il metodo CoUninitialize
, nessun RCW può essere usato dai thread non inizializzati in questo modo.
Effetto sull'ambiente di esecuzione
L'assistente al debug gestito non ha alcun effetto su CLR.
Output
Stato di apartment COM del thread corrente e stato che il codice stava tentando di applicare.
Impostazione
<mdaConfig>
<assistants>
<invalidApartmentStateChange />
</assistants>
</mdaConfig>
Esempio
L'esempio di codice seguente mostra una situazione che può comportare l'attivazione di questo assistente al debug gestito.
using System.Threading;
namespace ApartmentStateMDA
{
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
}
}
}