Recibe una excepción de System.Threading.ThreadStateException cuando intenta crear una instancia de un formulario Windows Forms


Síntomas


Cuando intenta crear una instancia de un formulario de Microsoft Windows que contiene un control ActiveX, puede recibir el siguiente mensaje de error:
Se ha producido una excepción no controlada del tipo 'System.Threading.ThreadStateException' en system.windows.forms.dll información adicional: no se puede instanciar el control ActiveX 'GUID' porque el subproceso actual no está en un apartamento de un único subproceso.
Nota: GUID es un marcador de posición para el GUID del control ActiveX. Nota: Este problema no puede producirse la primera vez que se ejecuta la aplicación.

Causa


El control ActiveX requiere que el subproceso crear instancias debe estar en un apartamento de un único subproceso (STA). Al crear instancias de subproceso es el subproceso que intenta crear una instancia del formulario Windows Forms. Sin embargo, el subproceso de crear instancias está en un apartamento multiproceso (MTA). Esto conduce a una condición de carrera que produce el problema que se menciona en la sección "Síntomas". Puede ser el subproceso crear instancias en un MTA si se cumple alguna de las condiciones siguientes:
  • En la aplicación host, utiliza el atributo MTAThread para especificar que el subproceso principal se ejecuta en un MTA.
  • En la aplicación host, se inicia un nuevo subproceso sin especificar el estado de apartamento del subproceso. En este caso, el subproceso se ejecuta en un MTA.
  • En la aplicación host, especifique el estado de apartamento de un subproceso nuevo como multiproceso antes de iniciar el subproceso.

Solución alternativa


Para evitar este problema, asegúrese de que se ejecute el subproceso crear instancias en STA. Si utiliza el atributo MTAThread para especificar que el subproceso principal de la aplicación host se ejecuta en un MTA, debe utilizar el atributo STAThread en su lugar. Para ello, siga estos pasos:
  1. En el código de la aplicación host, busque el código siguiente:
    <MTAThread()> _
  2. Reemplace el código que encontró en el paso anterior con el siguiente código:
    <STAThread()> _
  3. Crear la aplicación host y, a continuación, ejecute la aplicación host. No se produce el problema que se menciona en la sección "Síntomas".
Si inicia un nuevo subproceso sin especificar el estado de apartamento del subproceso, debe especificar el estado de apartamento del subproceso como un único subproceso. Para ello, siga estos pasos:
  1. Si inicia un subproceso que se denomina MyThread en el código de la aplicación host, busque el código siguiente:
    MyThread.Start()
  2. Agregue el código siguiente antes del código que encontró en el paso anterior:
    ' Specify that the MyThread thread runs in an STA.MyThread.ApartmentState = Threading.ApartmentState.STA
  3. Crear la aplicación host y, a continuación, ejecute la aplicación host. No se produce el problema que se menciona en la sección "Síntomas".
Si se especifica el estado de apartamento de un subproceso nuevo como multiproceso antes de iniciar el subproceso, debe especificar el estado de apartamento del subproceso como un único subproceso. Para ello, siga estos pasos:
  1. Si se especifica el estado de apartamento del subproceso MyThread como multiproceso en el código de la aplicación host, busque el código siguiente:
    MyThread.ApartmentState = Threading.ApartmentState.MTA
  2. Reemplace el código que encontró en el paso anterior con el siguiente código:
    ' Specify that the MyThread thread runs in an STA.MyThread.ApartmentState = Threading.ApartmentState.STA
  3. Crear la aplicación host y, a continuación, ejecute la aplicación host. No se produce el problema que se menciona en la sección "Síntomas".

Estado


Este comportamiento es una característica del diseño de la aplicación.

Más información


Pasos para reproducir el problema

  1. Inicie Microsoft Visual Studio .NET o Microsoft Visual Studio 2005.
  2. Utilice Microsoft Visual Basic .NET o Microsoft Visual Basic 2005 para crear un proyecto de aplicación para Windows. De forma predeterminada, se crea el formulario Form1 Windows.
  3. Agregar un control ActiveX, como el control de explorador Web de Microsoft al formulario Form1 Windows.
  4. Si desea especificar que el subproceso principal de la aplicación host se ejecuta en un MTA, siga estos pasos:
    1. En el archivo Form1.vb, busque el código siguiente:
      End Class
    2. Agregue el código siguiente antes del código que encontró en el paso anterior:
      <MTAThread()> _Public Shared Sub Main()   ' Run a standard application message loop on the current thread.   Application.Run(New Form1())End Sub
    Si desea iniciar un nuevo subproceso sin especificar el estado de apartamento del subproceso, siga estos pasos:
    1. En el archivo Form1.vb, busque el código siguiente:
      End Class
    2. Agregue el código siguiente antes del código que encontró en el paso anterior:
      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 desea especificar el estado de apartamento de un subproceso nuevo como multiproceso antes de iniciar el subproceso, siga estos pasos:
    1. En el archivo Form1.vb, busque el código siguiente:
      End Class
    2. Agregue el código siguiente antes del código que encontró en el paso anterior:
      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. Crear la aplicación host y, a continuación, ejecute la aplicación host. El problema que se menciona en la sección "Síntomas" puede producirse.

Referencias


Para obtener información adicional, visite la siguiente clase de ThreadStateException: sitios Web de MicrosoftMétodo Application.Run (formulario)Formulario de claseControles ActiveXProcesos, subprocesos y apartamentosThread (clase) Para obtener información adicional al respecto, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
316422 hoja de ruta para el subprocesamiento en Visual Basic .NET