2008-10-29 24 views
7

Tengo una aplicación Windows Forms (.NET) que puede tener varios documentos abiertos simultáneamente.Windows Forms - Multiple Event Loops

Sería conveniente tener cada documento (formulario) ejecutando su propio ciclo de eventos. Con una breve experimentación, el inicio de varios bucles de eventos en sus propios hilos STA parece funcionar. ¿Hay alguna razón por la cual esta es una mala idea?

+0

¿Por qué no solo ejecuta varias instancias, una por documento? –

+0

Nuestro tiempo de inicio es muy caro y nos gustaría poder comunicarnos entre documentos sin tener que usar IPC. – fuzzyman

Respuesta

4

Creo que está perfectamente bien crear múltiples bucles de mensajes en diferentes hilos. Lo único a lo que hay que tener cuidado es cuando se trata de herramientas de interfaz de usuario de terceros, a veces almacenan identificadores como miembros estáticos (en lugar de ThreadStatic) y si tiene múltiples subprocesos de interfaz de usuario en su aplicación, tendrá problemas (en mi caso, encontré que los aceleradores de teclado de la barra de herramientas/menú no funcionaban correctamente).

Una de las principales razones para hacer esto es si tiene cuadros de diálogo modales que aparecen en los diferentes cuadros de diálogo no modal. Si coloca todo en el mismo bucle de mensaje, si uno de los cuadros de diálogo no modal tiene un cuadro de diálogo modal, toda la aplicación (todas las ventanas) estará bloqueada hasta que cierre el cuadro de diálogo modal.

Y, como Kevin decía, ten cuidado con las llamadas de ventana cruzada (cross-window). Puede usar Control.BeginInvoke o Control.Invoke para publicar llamadas de delegado en los otros subprocesos de UI.

La otra cosa a considerar es cómo va a salir de su proceso. Lo más probable es que necesite realizar un seguimiento de los bucles de mensajes para poder detenerlos cuando desee cerrar todo. Si no te importa y solo quieres que el proceso finalice cuando todas las ventanas estén cerradas, puedes hacerlo también.

+0

Otra ventaja que vale la pena señalar es que obtienes una 'Application.ThreadException' por ciclo de mensajes. Puede usar esto para lógicamente "agrupar" ventanas juntas (por ejemplo, todas las ventanas que pertenecen a un caso de uso lógico/flujo de trabajo), darles un hilo dedicado y un bucle de mensajes, y capturar excepciones no controladas solo desde estas ventanas en 'Application.ThreadException' . – stakx

0

Solo tenga cuidado al acceder a los elementos de la GUI desde los hilos.

0

Los formularios no modificados pueden ser más adecuados para su propósito. Use form.Show() en lugar de form.ShowDialog().

+0

+1 de hecho. ¿No todos lo hacen así? Puede mostrar tantas formas como desee de esta manera. –

+0

Ya tenemos varias ventanas con formularios no modificados en una sola cadena de interfaz de usuario. Hay ciertos problemas con este enfoque que nos gustaría superar (queremos que algunos diálogos sean modales para una ventana individual pero no para todos los documentos abiertos, por ejemplo). – fuzzyman

1

Podría ser más inteligente utilizar un contenedor MDI (Multiple Document Interface) y formularios secundarios. En este caso, cada documento estaría en su propia forma, lo que técnicamente significa que cada documento tiene su propia cola de mensajes.

+1

Los contenedores MDI son una bendición desde el punto de vista del usuario. – fuzzyman

+1

MDI es REDUNDANTE de un POV de usuario dado que el escritorio ES un contenedor MDI. –

+0

¿Por qué todo esto odia a MDI? Las aplicaciones de MS Office son todas MDI. –

0

¿Por qué crees que necesitas más de un ciclo de mensajes? Un bucle de mensaje puede manejar cualquier cantidad de ventanas.

Si descubre que una operación de larga ejecución en una ventana es capaz de colgar toda la aplicación, la respuesta es dividir el trabajo de larga ejecución en algo como BackgroundWorker, dejando la IU receptiva.

La programación con varios subprocesos, cada uno con su propia interfaz de usuario, es mucho más complicada, porque un subproceso no puede acceder a ventanas y controles creados a partir de otro subproceso.

+2

Los diálogos modales bloquean toda la aplicación. * Los * necesitamos * para bloquear el formulario (documento) desde el que son llamados, pero no para bloquear toda la aplicación. – fuzzyman