Posible "spin off" varios hilos GUI? (Sin detener el sistema en Application.Run)

votos
20

Mi meta

Me gustaría tener un hilo de procesamiento principal (sin GUI), y poder separar las GUI en sus propios hilos de fondo según sea necesario, y tener mi hilo principal no GUI funcionando. Dicho de otra manera, quiero que mi hilo principal no GUI sea el propietario del hilo GUI y no al revés. No estoy seguro de que esto sea posible con Windows Forms (?)

Fondo

Tengo un sistema basado en componentes en el que un controlador carga dinámicamente ensamblajes, crea instancias y ejecuta clases que implementan una IComponentinterfaz común con un único método DoStuff().

Los componentes que se cargan se configuran mediante un archivo de configuración xml y agregando nuevos ensamblajes que contienen diferentes implementaciones de IComponent. Los componentes proporcionan funciones de utilidad a la aplicación principal. Mientras que el programa principal lo está haciendo, por ejemplo, controlar una planta nuclear, los componentes pueden realizar tareas de utilidad (en sus propios hilos), por ejemplo, limpiar la base de datos, enviar correos electrónicos e imprimir chistes graciosos en la impresora. Lo que me gustaría es que uno de estos componentes pueda mostrar una GUI, por ejemplo, con información de estado para dicho componente de envío de correo electrónico.

La vida útil del sistema completo se ve así

  1. La aplicación comienza.
  2. Verifique el archivo de configuración para los componentes a cargar. Cargarlos.
  3. Para cada componente, ejecute DoStuff()para inicializarlo y hacerlo vivir su propia vida en sus propios hilos.
  4. Continúa haciendo la aplicación principal, rey del trabajo, para siempre.

Todavía no he podido ejecutar el punto 3 si el componente activa una GUI en DoStuff(). Simplemente se detiene hasta que la GUI está cerrada. Y no hasta que se cierre la GUI, el programa pasa al punto 4.

Sería fantástico si a estos componentes se les permitiera iniciar sus propias GUI de Windows Forms.

Problema

Cuando un componente intenta encender una GUI DoStuff()(la línea exacta de código es cuando se ejecuta el componente Application.Run(theForm)), el componente y, por lo tanto, nuestro sistema se cuelga en la Application.Run()línea hasta que se cierra la GUI. Bueno, la GUI recién activada funciona bien, como se esperaba.

Ejemplo de componentes. Uno no tiene nada que ver con la interfaz gráfica de usuario, mientras que el segundo enciende una bonita ventana con conejitos mullidos de color rosa.

public class MyComponent1: IComponent
{
    public string DoStuff(...) { // write something to the database  }
}

public class MyComponent2: IComponent
{
    public void DoStuff()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form());

        // I want the thread to immediately return after the GUI 
        // is fired up, so that my main thread can continue to work.
    }
}

Lo he intentado sin suerte. Incluso cuando intento encender la GUI en su propio hilo, la ejecución se detiene hasta que la GUI está cerrada.

public void DoStuff()
{
    new Thread(ThreadedInitialize).Start()
}

private void ThreadedInitialize()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form());
}

¿Es posible derivar una GUI y regresar después Application.Run()?

Publicado el 05/08/2008 a las 22:19
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
11

El método Application.Run muestra uno (o más) formularios e inicia el ciclo de mensaje estándar que se ejecuta hasta que se cierran todos los formularios. No puede forzar un retorno de ese método excepto al cerrar todos sus formularios o forzar el cierre de una aplicación.

Sin embargo, puede pasar un ApplicationContext (en lugar de un nuevo Formulario ()) a Application.Run y ​​ApplicationContext se puede usar para ejecutar varios formularios a la vez. Su aplicación solo finalizará cuando todos estén cerrados. Vea aquí: http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx

Además, todos los formularios que muestre de forma no modal continuarán ejecutándose junto con su formulario principal, lo que le permitirá tener más de una ventana que no se bloquee entre sí. Creo que esto es realmente lo que estás tratando de lograr.

Respondida el 05/08/2008 a las 22:45
fuente por usuario

votos
0

No estoy seguro de si esto es correcto, sin embargo recuerdo haber ejecutado formularios de ventana desde una aplicación de consola simplemente al actualizar el formulario y al llamar a newForm.Show () en él, si sus componentes usan eso en lugar de Application.Run (), entonces el nuevo la forma no debe bloquear.

Por supuesto, el componente será responsable de mantener una referencia a las formas que crea

Respondida el 23/05/2009 a las 22:57
fuente por usuario

votos
0

Estoy seguro de que esto es posible si lo pirateas lo suficiente, pero sugiero que no es una buena idea.

'Windows' (que se ve en la pantalla) están muy relacionados con los procesos. Es decir, se espera que cada proceso que muestre cualquier GUI tenga un bucle de mensajes, que procesa todos los mensajes relacionados con la creación y administración de ventanas (cosas como 'hacer clic en el botón', 'cerrar la aplicación', 'volver a dibujar la pantalla ' y así.

Debido a esto, se supone más o menos que si tiene un bucle de mensaje, debe estar disponible durante el tiempo de vida de su proceso. Por ejemplo, Windows podría enviarle un mensaje de 'abandono', y usted debe tener un bucle de mensajes disponible para manejarlo, incluso si no tiene nada en la pantalla.

Tu mejor opción es hacerlo así:

Haga una forma falsa que nunca se muestre, que es su aplicación principal. Inicie la aplicación de llamadas. Ejecute y pase en esta forma falsa. Haz tu trabajo en otro hilo, y dispara eventos en el hilo principal cuando necesites hacer cosas Gui.

Respondida el 06/08/2008 a las 00:22
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more