Vous recevez une exception System.Threading.ThreadStateException lorsque vous essayez de créer une instance d’un Windows form


Symptômes


Lorsque vous essayez de créer une instance d’un formulaire Microsoft Windows qui contient un contrôle ActiveX, le message d’erreur suivant s’affiche :
Une exception non gérée du type 'System.Threading.ThreadStateException' s’est produite dans system.windows.forms.dll informations supplémentaires : Impossible d’instancier le contrôle ActiveX 'GUID' car le thread actuel ne se trouve pas dans un single-threaded apartment.
Remarque : GUID est un espace réservé pour le GUID du contrôle ActiveX. Remarque Ce problème ne peut pas se produire la première fois que vous exécutez votre application.

Cause


Le contrôle ActiveX nécessite que l’instanciation du thread doit être dans un single-threaded apartment (STA). L’instanciation du thread est le thread qui essaie de créer une instance du Windows form. Toutefois, l’instanciation du thread est dans un MTA (multithreaded apartment). Cela conduit à une condition de concurrence qui provoque le problème mentionné dans la section « Symptômes ». L’instanciation du thread peut être dans un MTA si une des conditions suivantes est remplie :
  • Dans l’application hôte, vous utilisez l’attribut MTAThread pour indiquer que le thread principal s’exécute dans un MTA.
  • Dans l’application hôte, vous démarrez un nouveau thread sans spécifier l’état de cloisonnement du thread. Dans ce cas, le thread s’exécute dans un MTA.
  • Dans l’application hôte, vous spécifiez l’état de cloisonnement d’un thread en mode multithread avant le démarrage du thread.

Solution de contournement


Pour contourner ce problème, assurez-vous que l’instanciation thread s’exécute dans un STA. Si vous utilisez l’attribut MTAThread pour indiquer que le thread principal de l’application hôte s’exécute dans un MTA, vous devez utiliser l’attribut STAThread à la place. Pour ce faire, procédez comme suit :
  1. Dans le code de votre application hôte, recherchez le code suivant :
    <MTAThread()> _
  2. Remplacez le code que vous avez localisée à l’étape précédente par le code suivant :
    <STAThread()> _
  3. Génération de votre application hôte et exécutez votre application hôte. Le problème qui est mentionné dans la section » Symptômes"ne se produit pas.
Si vous démarrez un nouveau thread sans spécifier l’état de cloisonnement du thread, vous devez spécifier l’état de cloisonnement du thread sous la forme d’un seul thread. Pour ce faire, procédez comme suit :
  1. Si vous démarrez un thread nommé MyThread dans le code de votre application hôte, recherchez le code suivant :
    MyThread.Start()
  2. Ajoutez le code suivant avant le code que vous avez localisée à l’étape précédente :
    ' Specify that the MyThread thread runs in an STA.MyThread.ApartmentState = Threading.ApartmentState.STA
  3. Génération de votre application hôte et exécutez votre application hôte. Le problème qui est mentionné dans la section » Symptômes"ne se produit pas.
Si vous spécifiez l’état de cloisonnement d’un thread en mode multithread avant le démarrage du thread, vous devez spécifier l’état de cloisonnement du thread sous la forme d’un seul thread à la place. Pour ce faire, procédez comme suit :
  1. Si vous spécifiez l’état de cloisonnement du thread MyThread en mode multithread dans le code de votre application hôte, recherchez le code suivant :
    MyThread.ApartmentState = Threading.ApartmentState.MTA
  2. Remplacez le code que vous avez localisée à l’étape précédente par le code suivant :
    ' Specify that the MyThread thread runs in an STA.MyThread.ApartmentState = Threading.ApartmentState.STA
  3. Génération de votre application hôte et exécutez votre application hôte. Le problème qui est mentionné dans la section » Symptômes"ne se produit pas.

Statut


Ce comportement est inhérent au produit.

Informations supplémentaires


Procédure pour reproduire le problème

  1. Démarrez Microsoft Visual Studio .NET ou Microsoft Visual Studio 2005.
  2. Utilisez Microsoft Visual Basic .NET ou Microsoft Visual Basic 2005 pour créer un projet d’Application Windows. Par défaut, le formulaire Windows de Form1 est créé.
  3. Ajouter n’importe quel contrôle ActiveX, tel que le contrôle de navigateur Web Microsoft, à l’écran Windows de Form1.
  4. Si vous souhaitez indiquer que le thread principal de l’application hôte s’exécute dans un MTA, procédez comme suit :
    1. Dans le fichier Form1.vb, recherchez le code suivant :
      End Class
    2. Ajoutez le code suivant avant le code que vous avez localisée à l’étape précédente :
      <MTAThread()> _Public Shared Sub Main()   ' Run a standard application message loop on the current thread.   Application.Run(New Form1())End Sub
    Si vous souhaitez démarrer un nouveau thread sans spécifier l’état de cloisonnement du thread, procédez comme suit :
    1. Dans le fichier Form1.vb, recherchez le code suivant :
      End Class
    2. Ajoutez le code suivant avant le code que vous avez localisée à l’étape précédente :
      Public Shared Sub Main()   ' Create a thread. Then run the LaunchForm method on the thread.   ' This automatically runs the main thread in the application in an MTA.   Dim MyThread As System.Threading.Thread   MyThread = New System.Threading.Thread(AddressOf LaunchForm)   MyThread.Start()End SubPublic Shared Sub LaunchForm()   ' Run a standard application message loop on the current thread.   Application.Run(New Form1())End Sub
    Si vous souhaitez spécifier l’état de cloisonnement d’un thread en mode multithread avant que le thread est démarré, procédez comme suit :
    1. Dans le fichier Form1.vb, recherchez le code suivant :
      End Class
    2. Ajoutez le code suivant avant le code que vous avez localisée à l’étape précédente :
      Public Shared Sub Main()   ' Create a thread. Then run the LaunchForm method on the thread.   Dim MyThread As System.Threading.Thread   MyThread = New System.Threading.Thread(AddressOf LaunchForm)   ' Specify that the MyThread thread runs in an MTA.   MyThread.ApartmentState = Threading.ApartmentState.MTA   MyThread.Start()End SubPublic Shared Sub LaunchForm()   ' Run a standard application message loop on the current thread.   Application.Run(New Form1())End Sub
  5. Génération de votre application hôte et exécutez votre application hôte. Le problème qui est mentionné dans la section « Symptômes » peut se produire.

Références


Pour plus d’informations, consultez la classe sites : ThreadStateException de Web de Microsoft à l’adresse suivanteApplication.Run, méthode (écran)Classe de formulaireContrôles ActiveXProcessus, threads et apartments (cloisonnés)Classe de threadPour plus d’informations, cliquez sur le numéro ci-dessous pour afficher l’article correspondant dans la Base de connaissances Microsoft :
Introduction à la documentation pour les threads dans Visual Basic .NET 316422