Partager via


Assistant Débogage managé invalidApartmentStateChange

Remarque

Cet article est spécifique au .NET Framework. Elle ne s’applique pas aux implémentations plus récentes de .NET, notamment .NET 6 et versions ultérieures.

L’Assistant Débogage managé invalidApartmentStateChange est activé par l’un des deux problèmes suivants :

  • Une tentative est effectuée pour modifier l’état de cloisonnement COM d’un thread qui a déjà été initialisé par COM à un état de cloisonnement différent.

  • L’état de cloisonnement COM d’un thread change de manière inopinée.

Symptômes

  • L’état de cloisonnement COM d’un thread ne correspond pas à ce qui a été demandé. Cela peut entraîner l’utilisation de proxies pour des composants COM qui ont un modèle de thread différent du modèle courant. Cela peut également provoquer la levée d’une InvalidCastException lors de l’appel de l’objet COM via des interfaces qui ne sont pas définies pour le marshaling entre cloisonnements.

  • L’état de cloisonnement COM du thread est différent de celui qui est attendu. Cela peut provoquer une COMException avec la valeur HRESULT RPC_E_WRONG_THREAD ainsi qu’une InvalidCastException quand des appels sont effectués sur un wrapper RCW (Runtime Callable Wrapper). Cela peut également conduire plusieurs threads à accéder en même temps à certains composants COM à thread unique, ce qui risque d’entraîner une altération ou une perte de données.

Cause

  • Le thread a été précédemment initialisé à un état de cloisonnement COM différent. Notez que l’état de cloisonnement d’un thread peut être défini explicitement ou implicitement. Les opérations explicites incluent la propriété Thread.ApartmentState et les méthodes SetApartmentState et TrySetApartmentState. MTA est implicitement affecté à un thread créé à l’aide de la méthode Start, à moins que SetApartmentState ne soit appelé avant le démarrage du thread. De même, la valeur MTA est implicitement affectée au thread principal de l’application, à moins que l’attribut STAThreadAttribute ne soit spécifié sur la méthode principale.

  • La méthode CoUninitialize (ou la méthode CoInitializeEx) avec un modèle de concurrence différent est appelée sur le thread.

Résolution

Définissez l’état de cloisonnement du thread avant que son exécution ne commence ou appliquez l’attribut STAThreadAttribute ou l’attribut MTAThreadAttribute à la méthode principale de l’application.

Dans l’idéal, pour la deuxième cause, le code qui appelle la méthode CoUninitialize doit être modifié pour différer l’appel jusqu’à ce que le thread soit sur le point de s’arrêter et qu’aucun des RCW ou de leurs composants COM sous-jacents ne soient encore utilisés par le thread. Toutefois, s’il est impossible de modifier le code qui appelle la méthode CoUninitialize, aucun RCW ne doit être utilisé par des threads non initialisés de cette façon.

Effet sur le runtime

Cet Assistant Débogage managé n'a aucun effet sur le CLR.

Sortie

État de cloisonnement COM du thread actuel et état que le code tentait d’appliquer.

Configuration

<mdaConfig>
  <assistants>
    <invalidApartmentStateChange />
  </assistants>
</mdaConfig>

Exemple

L’exemple de code suivant illustre une situation qui peut activer cet Assistant Débogage managé.

using System.Threading;
namespace ApartmentStateMDA
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
        }
    }
}

Voir aussi