2009-08-03 17 views
5

Por favor, echar un vistazo al siguiente código:Application.Run() en diferentes hilos

var splashForm = new SplashForm(); 
m_Thread = new Thread(() => System.Windows.Forms.Application.Run(splashForm)) 
m_Thread.Start(); 

// Do some initialization 
// ... 

// the following method just invokes `Close()` on the right thread 
splashForm.Shutdown(); 

// Loop until the thread is no longer alive 
// ... 

System.Windows.Forms.Application.Run(mainForm); 

Parece como si todo funciona bien: en primer lugar veo la pantalla de bienvenida, después el formulario principal se inicia. Pero de alguna manera obtengo errores extraños, como: los elementos gráficos (una ProgressBar sin fin) no se muestran correctamente.
EDIT: Tengo dos barras de progreso, una en la pantalla secundaria, en la forma principal. Ambos muestran el mismo comportamiento (incorrecto) en el modo sin fin: no hay progreso, solo el fondo puro. /EDIT
En mi opinión, esto se debe a la llamada de Application.Run() en diferentes hilos. Este error puede ser eliminado por llamar a cualquier función/propiedad de la mainForm antes de iniciar la pantalla de bienvenida - como, por ejemplo

mainForm.Text = mainForm.Text; 

Puede alguien por favor confirmar que este código puede causar problemas - o que debería comportarse bien y no tengo para buscar el error en otro lugar?
Ya busqué implementaciones de pantalla de bienvenida y sé que se puede hacer de manera diferente. Pero estoy interesado en comprender esta implementación y sus posibles problemas. ¡Gracias!

+0

Las barras de progreso pueden ser un poco especiales, ya que pueden truncar su propio hilo para hacer esa cosa de marquesina. ¿Puedes aislar y describir lo que sucede? Como usar un PB bloqueado, agregue un PB con valor = 50, etc. –

Respuesta

1

OMG, encontré la respuesta:
Application.EnableVisualStyles(); fue llamado en el ctor si mi mainForm (¿por qué?). Se debe invocar antes de que se creen controles. Moverlo al static Main() hizo el truco. Los estilos visuales son necesarios para barras de progreso sin fin (ProgressBarStyle.Marquee).
Ahora esta solución de pantalla de bienvenida funciona como debería.

+0

esto podría haber funcionado para ti. Pero lo hubiera hecho de manera un poco diferente. Supongo que quieres mostrar la pantalla de bienvenida solo durante la carga. Entonces, ¿por qué crear una bomba de mensajes para el hilo en el que se crea la pantalla de bienvenida? En su lugar, simplemente llámelo en un hilo separado llamando a Show y cuando termine, simplemente llame a close. Ahora, cree la bomba de mensajes llamando a Application.Run (mainForm) –

+0

Sí, puede que tenga razón. La llamada adicional a Application.Run() se puede omitir probablemente, voy a comprobar esto. – tanascius

3

Yo crearía el formulario en la secuencia donde se ejecuta Application.Run().

SplashForm splashForm = null; 
m_Thread = new Thread(delegate { splashForm = new SplashForm(); System.Windows.Forms.Application.Run(splashForm); }); 
m_Thread.Start(); 

Pero lo que realmente hay que hacer es acceder a ella a través de la técnica de InvokeRequired y BeginInvoke. Compruebe here.

+0

No, yo también lo pensé, pero creo que la afinidad de la banda de rodamiento se establece mediante el método Ejecutar. –

+0

Bueno, eso es solo la mitad. La parte principal es en realidad la parte InvokeRequired como sugiere el artículo vinculado. –

+0

Sí, para cualquier comunicación entre los 2 hilos, como siempre. –

1

No hay nada principalmente mal con lo que está haciendo. Me pareció que el enfoque era lo suficientemente interesante como para impulsar una demostración, y funciona bien. También puedo decir que la respuesta de kek444 no es el problema. Crear SplahForm en el hilo principal no hizo diferencia.

Así que supongo que es en la forma en que controla el Progressbar, o más en general, cómo se comunica entre los 2 hilos.

+0

Hay una barra de progreso en la pantalla de presentación: en modo continuo, no muestra ningún progreso (solo el fondo).Más adelante en la forma principal hay una barra de progreso, que muestra el mismo comportamiento en modo interminable: nada ... – tanascius

+0

Estoy ejecutando un PBar en un temporizador, no hay problema. ¿Cómo empujas los nuevos valores? –

+0

No estoy presionando valores; simplemente configuré el estilo en ProgressBarStyle.Marquee. – tanascius

4

El hilo en el que se muestra su SplashForm necesita tener una bomba de mensajes de Windows para procesar los mensajes que genera cada ventana/control. Para hacer eso, necesitas hacer que el hilo sea un hilo STA. Trate de llamar SetApartmentStateantes de comenzar el hilo

+0

Estoy ejecutando un SplashForm en un hilo MTA muy bien. ¿Tiene alguna referencia sobre los requisitos de MessageLoop y STA/MTA? –

+0

Configuré el ApartmentState usando m_Thread.TrySetApartmentState (ApartmentState.STA); Desafortunadamente no ayuda. – tanascius

+0

Esto es lo mejor que pude encontrar con una búsqueda breve: http://blogs.msdn.com/jfoscoding/archive/2005/04/07/406341.aspx –

Cuestiones relacionadas