2011-01-11 29 views
17

Cuando crea una aplicación vacía WinForms con Visual Studio, la plantilla tiene el atributo STAThread en la clase de aplicación principal.¿Por qué las aplicaciones WinForms STATread de forma predeterminada?

He estado leyendo algunos documentos al respecto, pero no estoy seguro de haberlo entendido.

Realmente tengo algunas preguntas al respecto:

  1. Por qué se añade este atributo?
  2. ¿Qué significa?
  3. ¿Qué ocurre si elimina este atributo?
+2

Posible duplicado: http://stackoverflow.com/questions/102437/why-do-all-winforms-programs-require-the-stathread-attribute –

+0

@Cody: Sí, lo siento, no lo vi, pero en mi humilde opinión esta respuesta es mucho mejor que la otra. –

+1

Sí, eso es justo. No voté para cerrar porque esas respuestas no fueron fantásticas. El conocimiento más importante para obtener de esa pregunta es este enlace: http://blogs.msdn.com/b/jfoscoding/archive/2005/04/07/406341.aspx –

Respuesta

12

1. ¿Por qué se agrega este atributo?

Porque es requerido por el modelo de objetos ActiveX. Y puede soltar los controles ActiveX en un WinForm (por lo tanto, existe compatibilidad) O algunas clases .NET usan controles nativos que requieren ese atributo.

2. ¿Qué significa?

Significa que el hilo se ejecuta en el single-threaded apartment model.

3. ¿Qué sucede si elimina este atributo?

Si se elimina el atributo, el comportamiento no está definido. El programa puede fallar al azar, con mensajes de error a veces razonables. Por ejemplo, las cosas pueden funcionar ahora, luego rompa con un paquete de servicio.

+1

El mayor problema con el que se encontrará es COM interopera. Y no digas que no estás haciendo esto y no te importa: Windows hace muchas cosas bajo las sábanas. –

+0

Al menos, WPF se niega a trabajar en MTA y lanza una excepción de inmediato. Podría ser que WinForms lo haga también. – Joey

+1

No son solo controles ActiveX, sino muchas otras cosas dependen de ello. El portapapeles, arrastrar + soltar, cualquiera de los cuadros de diálogo del shell como OpenFileDialog. Además de muchos contenedores .NET que usan una API COM bajo el capó. Esa es toda la interoperabilidad COM que no se puede ver, pero que solo funciona correctamente en un hilo STA. Incluso el CLR es consciente de ello, Thread.Join() bombea un bucle de mensaje, por ejemplo, cuando se le llama en un subproceso de interfaz de usuario. –

19

citar de an MSDN blog,

Cuando se aplica el STAThreadAttribute, cambia el estado de apartamento del subproceso actual a ser de un solo subproceso. Sin entrar en una gran discusión sobre COM y threading, este atributo asegura el mecanismo de comunicación entre el hilo actual y otros hilos que pueden querer hablar a través de COM. Cuando usa Windows Forms, dependiendo de la característica que esté utilizando, puede estar utilizando la interoperabilidad COM para comunicarse con los componentes del sistema operativo. Buenos ejemplos de esto son el Portapapeles y los Diálogos de Archivos.

+0

Sería bueno si pusiera un enlace al blog en su respuesta. – GEOCHET

0

Significa que los programas de Windows Forms usan un estado de un solo subproceso. MTA y estados de apartamento de rosca libre no son compatibles.

3

3. ¿Qué sucede si elimina este atributo?

Acabo de agregar un ejemplo simple que demuestra el problema.

Creé la aplicación WinForms simple con un botón y un OpenFileDialog. En el botón, haga clic en Ejecutar un hilo que muestra OpenFileDialog. Lanzo la aplicación con y sin STAThread y los resultados de hacer clic en el botón son los mismos: arroja la excepción "Operación entre hilos no válida: Control 'Form1' al que se accede desde un hilo que no sea el hilo en el que se creó". Parece que no hay diferencia. Pero no.

Entonces cambió muestra la OpenFileDialog mediante una llamada al método siguiente:

private void ShowOFD() 
{ 
    if (InvokeRequired) 
    { 
     BeginInvoke(new Action(ShowOFD)); 
     return; 
    } 

    openFileDialog1.ShowDialog(this); 
} 

Con STAThread funciona bien como se esperaba. Sin STAThread arroja la excepción: "El hilo actual debe configurarse en modo de apartamento de una sola rosca (STA) antes de que se puedan realizar llamadas OLE. Asegúrese de que su función Principal tenga marcado STAThreadAttribute. Esta excepción solo se genera si se conecta un depurador al proceso ".

Luego ejecuto la aplicación varias veces sin depurador (separado de Visual Studio). Una vez que la aplicación simplemente cerró silenciosamente, en otra ocasión la aplicación se cerró con el mensaje "vshost ha dejado de funcionar"

Cuestiones relacionadas