Ventana Mdi con ventanas hijas en threads

24/11/2004 - 17:57 por Kano | Informe spam
Veamos tengo una aplicación con la ventana principal mdi q contiene
ventanas hijas.
Quiero montar las ventanas hijas cada una en un thread
Tengo una clase que pasandole la clase del formulario y la ventana padre
debe encargarse de crear el thread montar la ventana y visualizarla.
Funciona todo correctamente menos la linea en la que se asigna la
propiedad de MdiParent del formulario que me da una excecion con el
mensaje "Controls created on one thread cannot be parented to a control
on a different thread."
El codigo es el siguiente


private class b_i_window_threader
//el hilador de ventanas
{
private Object i_frm;
private Thread i_th_frm;
private Type i_t_tipo;
private Form i_frm_padre;
public b_i_window_threader(Type tipo,Form Padre)
{
i_t_tipo=tipo;
i_frm_padre=Padre;
i_th_frm= new Thread(new ThreadStart(carga));
i_th_frm.Start();
}
public void carga()
{
i_frm = Activator.CreateInstance(i_t_tipo);
String key = Guid.NewGuid().ToString();
((Form)i_frm).AccessibleName = key;
/*error*/ ((Form)i_frm).MdiParent =i_frm_padre ;
i_th_frm.Name=((Form)i_frm).Text;
Application.Run((Form)i_frm);
}
}

como puedo evitar este problema?

Gracias por adelantado:
Kano

Preguntas similare

Leer las respuestas

#1 pablo crosio
25/11/2004 - 00:55 | Informe spam
hola!

no se si te sirva pero yo realice una implementacion similar de la siguiente
forma:

creo los mdi hijos en el thread principal y luego creo nuevos threads para
ejecutar los metodos propios de los mdi.

ademas por lo que veo estas creando tantos loops de mensajes por cada hijo
que tenes, quizas te convenga trabajar con el loop de mensajes del formulario
mdi padre solamente los mensajes se redireccionan automaticamente a la
ventana hija que corresponda...

salu2!!

pablo

"Kano" escribió:

Veamos tengo una aplicación con la ventana principal mdi q contiene
ventanas hijas.
Quiero montar las ventanas hijas cada una en un thread
Tengo una clase que pasandole la clase del formulario y la ventana padre
debe encargarse de crear el thread montar la ventana y visualizarla.
Funciona todo correctamente menos la linea en la que se asigna la
propiedad de MdiParent del formulario que me da una excecion con el
mensaje "Controls created on one thread cannot be parented to a control
on a different thread."
El codigo es el siguiente


private class b_i_window_threader
//el hilador de ventanas
{
private Object i_frm;
private Thread i_th_frm;
private Type i_t_tipo;
private Form i_frm_padre;
public b_i_window_threader(Type tipo,Form Padre)
{
i_t_tipo=tipo;
i_frm_padre=Padre;
i_th_frm= new Thread(new ThreadStart(carga));
i_th_frm.Start();
}
public void carga()
{
i_frm = Activator.CreateInstance(i_t_tipo);
String key = Guid.NewGuid().ToString();
((Form)i_frm).AccessibleName = key;
/*error*/ ((Form)i_frm).MdiParent =i_frm_padre ;
i_th_frm.Name=((Form)i_frm).Text;
Application.Run((Form)i_frm);
}
}

como puedo evitar este problema?

Gracias por adelantado:
Kano

Respuesta Responder a este mensaje
#2 Kano
25/11/2004 - 15:36 | Informe spam
buenas pablo.
que esexactamente un loop de mensajes.
Al final ya he resuelto el problema de montar los formularios mdi hijos
en threads (engañando un poco al ensamblador) ahora el problema lo tengo
cuando creo un tercer nivel de threads desde los propisos formularios
mdi hijos para los procesos internos de los formularios.
desde un formulario hijo creo q thread, lo lanzo y cuando hago un join
para q el thread del mdi hijo espere al de proceso, el q se duerme es el
thread principal!
te juro que cuando haga funcionar esto me tomare una semana dew
vacaciones como premio.

Un saludo



pablo crosio wrote:
hola!

no se si te sirva pero yo realice una implementacion similar de la siguiente
forma:

creo los mdi hijos en el thread principal y luego creo nuevos threads para
ejecutar los metodos propios de los mdi.

ademas por lo que veo estas creando tantos loops de mensajes por cada hijo
que tenes, quizas te convenga trabajar con el loop de mensajes del formulario
mdi padre solamente los mensajes se redireccionan automaticamente a la
ventana hija que corresponda...

salu2!!

pablo

"Kano" escribió:


Veamos tengo una aplicación con la ventana principal mdi q contiene
ventanas hijas.
Quiero montar las ventanas hijas cada una en un thread
Tengo una clase que pasandole la clase del formulario y la ventana padre
debe encargarse de crear el thread montar la ventana y visualizarla.
Funciona todo correctamente menos la linea en la que se asigna la
propiedad de MdiParent del formulario que me da una excecion con el
mensaje "Controls created on one thread cannot be parented to a control
on a different thread."
El codigo es el siguiente


private class b_i_window_threader
//el hilador de ventanas
{
private Object i_frm;
private Thread i_th_frm;
private Type i_t_tipo;
private Form i_frm_padre;
public b_i_window_threader(Type tipo,Form Padre)
{
i_t_tipo=tipo;
i_frm_padre=Padre;
i_th_frm= new Thread(new ThreadStart(carga));
i_th_frm.Start();
}
public void carga()
{
i_frm = Activator.CreateInstance(i_t_tipo);
String key = Guid.NewGuid().ToString();
((Form)i_frm).AccessibleName = key;
/*error*/ ((Form)i_frm).MdiParent =i_frm_padre ;
i_th_frm.Name=((Form)i_frm).Text;
Application.Run((Form)i_frm);
}
}

como puedo evitar este problema?

Gracias por adelantado:
Kano





Kano



pablo crosio wrote:
hola!

no se si te sirva pero yo realice una implementacion similar de la


siguiente
forma:

creo los mdi hijos en el thread principal y luego creo nuevos threads


para
ejecutar los metodos propios de los mdi.

ademas por lo que veo estas creando tantos loops de mensajes por cada


hijo
que tenes, quizas te convenga trabajar con el loop de mensajes del


formulario
mdi padre solamente los mensajes se redireccionan automaticamente


a la
ventana hija que corresponda...

salu2!!

pablo

"Kano" escribió:


Veamos tengo una aplicación con la ventana principal mdi q contiene
ventanas hijas.
Quiero montar las ventanas hijas cada una en un thread
Tengo una clase que pasandole la clase del formulario y la ventana padre
debe encargarse de crear el thread montar la ventana y visualizarla.
Funciona todo correctamente menos la linea en la que se asigna la
propiedad de MdiParent del formulario que me da una excecion con el
mensaje "Controls created on one thread cannot be parented to a control
on a different thread."
El codigo es el siguiente


private class b_i_window_threader
//el hilador de ventanas
{
private Object i_frm;
private Thread i_th_frm;
private Type i_t_tipo;
private Form i_frm_padre;
public b_i_window_threader(Type tipo,Form Padre)
{
i_t_tipo=tipo;
i_frm_padre=Padre;
i_th_frm= new Thread(new ThreadStart(carga));
i_th_frm.Start();
}
public void carga()
{
i_frm = Activator.CreateInstance(i_t_tipo);
String key = Guid.NewGuid().ToString();
((Form)i_frm).AccessibleName = key;
/*error*/ ((Form)i_frm).MdiParent =i_frm_padre ;
i_th_frm.Name=((Form)i_frm).Text;
Application.Run((Form)i_frm);
}
}

como puedo evitar este problema?

Gracias por adelantado:
Kano

Respuesta Responder a este mensaje
#3 pablo crosio
25/11/2004 - 19:19 | Informe spam
hola!

basicamente un loop de mensajes es un ciclo que utilizan las aplicaciones
windows para manejar los mensajes recibidos como pueden ser el movimiento del
mouse, una tecla, un click en un menu, etc... esos mensajes dependiendo de
en donde se generen deberan ser tratados por la ventana a la que van
dirigidos... una vez que se cierra la ventana principal manejadora de los
mensajes, el ciclo termina y finalizaria la aplicacion

en C# con Application.Run( ) estas inicializando un ciclo de mensajes

el tema es que estos ciclos de mensajes generalmente se manejan por
threads es decir habria uno por cada thread (aunque no necesariamente)...

lo que yo te proponia era que tuvieras un solo ciclo (un solo
Application.Run()) en el principal... y no por cada hijo
pero vos si o si queres lanzar ventanas hijas en otros threads... y ahi
hasta donde se no te queda otra que generar nuevos loops de mensajes por cada
hijo

la alternativa que te planteaba yo era que lanzaras los hijos desde el
thread principal y solamente utilizaras nuevos threads para los procesos...

lo que no me queda claro es como se duerme el thread principal

tal vez si escribes algo de la logica del proceso podamos darte una ayuda

salu2!!

pablo





"Kano" escribió:

buenas pablo.
que esexactamente un loop de mensajes.
Al final ya he resuelto el problema de montar los formularios mdi hijos
en threads (engañando un poco al ensamblador) ahora el problema lo tengo
cuando creo un tercer nivel de threads desde los propisos formularios
mdi hijos para los procesos internos de los formularios.
desde un formulario hijo creo q thread, lo lanzo y cuando hago un join
para q el thread del mdi hijo espere al de proceso, el q se duerme es el
thread principal!
te juro que cuando haga funcionar esto me tomare una semana dew
vacaciones como premio.

Un saludo



pablo crosio wrote:
> hola!
>
> no se si te sirva pero yo realice una implementacion similar de la siguiente
> forma:
>
> creo los mdi hijos en el thread principal y luego creo nuevos threads para
> ejecutar los metodos propios de los mdi.
>
> ademas por lo que veo estas creando tantos loops de mensajes por cada hijo
> que tenes, quizas te convenga trabajar con el loop de mensajes del formulario
> mdi padre solamente los mensajes se redireccionan automaticamente a la
> ventana hija que corresponda...
>
> salu2!!
>
> pablo
>
> "Kano" escribió:
>
>
>>Veamos tengo una aplicación con la ventana principal mdi q contiene
>>ventanas hijas.
>>Quiero montar las ventanas hijas cada una en un thread
>>Tengo una clase que pasandole la clase del formulario y la ventana padre
>>debe encargarse de crear el thread montar la ventana y visualizarla.
>>Funciona todo correctamente menos la linea en la que se asigna la
>>propiedad de MdiParent del formulario que me da una excecion con el
>>mensaje "Controls created on one thread cannot be parented to a control
>>on a different thread."
>>El codigo es el siguiente
>>
>>
>>private class b_i_window_threader
>>//el hilador de ventanas
>>{
>> private Object i_frm;
>> private Thread i_th_frm;
>> private Type i_t_tipo;
>> private Form i_frm_padre;
>> public b_i_window_threader(Type tipo,Form Padre)
>> {
>> i_t_tipo=tipo;
>> i_frm_padre=Padre;
>> i_th_frm= new Thread(new ThreadStart(carga));
>> i_th_frm.Start();
>> }
>> public void carga()
>> {
>> i_frm = Activator.CreateInstance(i_t_tipo);
>> String key = Guid.NewGuid().ToString();
>> ((Form)i_frm).AccessibleName = key;
>>/*error*/ ((Form)i_frm).MdiParent =i_frm_padre ;
>> i_th_frm.Name=((Form)i_frm).Text;
>> Application.Run((Form)i_frm);
>> }
>>}
>>
>>como puedo evitar este problema?
>>
>>Gracias por adelantado:
>>Kano
>>
Kano



pablo crosio wrote:
> hola!
>
> no se si te sirva pero yo realice una implementacion similar de la
siguiente
> forma:
>
> creo los mdi hijos en el thread principal y luego creo nuevos threads
para
> ejecutar los metodos propios de los mdi.
>
> ademas por lo que veo estas creando tantos loops de mensajes por cada
hijo
> que tenes, quizas te convenga trabajar con el loop de mensajes del
formulario
> mdi padre solamente los mensajes se redireccionan automaticamente
a la
> ventana hija que corresponda...
>
> salu2!!
>
> pablo
>
> "Kano" escribió:
>
>
>>Veamos tengo una aplicación con la ventana principal mdi q contiene
>>ventanas hijas.
>>Quiero montar las ventanas hijas cada una en un thread
>>Tengo una clase que pasandole la clase del formulario y la ventana padre
>>debe encargarse de crear el thread montar la ventana y visualizarla.
>>Funciona todo correctamente menos la linea en la que se asigna la
>>propiedad de MdiParent del formulario que me da una excecion con el
>>mensaje "Controls created on one thread cannot be parented to a control
>>on a different thread."
>>El codigo es el siguiente
>>
>>
>>private class b_i_window_threader
>>//el hilador de ventanas
>>{
>> private Object i_frm;
>> private Thread i_th_frm;
>> private Type i_t_tipo;
>> private Form i_frm_padre;
>> public b_i_window_threader(Type tipo,Form Padre)
>> {
>> i_t_tipo=tipo;
>> i_frm_padre=Padre;
>> i_th_frm= new Thread(new ThreadStart(carga));
>> i_th_frm.Start();
>> }
>> public void carga()
>> {
>> i_frm = Activator.CreateInstance(i_t_tipo);
>> String key = Guid.NewGuid().ToString();
>> ((Form)i_frm).AccessibleName = key;
>>/*error*/ ((Form)i_frm).MdiParent =i_frm_padre ;
>> i_th_frm.Name=((Form)i_frm).Text;
>> Application.Run((Form)i_frm);
>> }
>>}
>>
>>como puedo evitar este problema?
>>
>>Gracias por adelantado:
>>Kano
>>

Respuesta Responder a este mensaje
#4 Kano
26/11/2004 - 09:20 | Informe spam
No sabia lo q era un loop de mensajes ... siempre hay cosas nueva a
aprender :)
al final el cargador de ventanas se ha quedado asi

public class b_i_window_threader
//el hilador de ventanas
{
private Object i_frm;
private Thread i_th_frm;
private Type i_t_tipo;
private Form i_frm_padre;
public b_i_window_threader(Type tipo,Form Padre)
{
i_t_tipo=tipo;
i_frm_padre=Padre;
i_frm = Activator.CreateInstance(i_t_tipo);
i_th_frm= new Thread(new ThreadStart(carga));
i_th_frm.Start();
((Form)i_frm).MdiParent=Padre;
}
private void carga()
{
//i_frm = Activator.CreateInstance(i_t_tipo);
String key = Guid.NewGuid().ToString();
((Form)i_frm).AccessibleName = key;
((Form)i_frm).MdiParent =i_frm_padre ;
i_th_frm.Name=((Form)i_frm).Text;
Application.Run((Form)i_frm);
}
}

Si cambio la linea de "Application.Run((Form)i_frm);" por un
"((Form)i_frm).Show();" la cosa no funciona, se muestra el formulario y
luego se cierra.

Despues dentro de la ventana, q se carga correctamente en el hilo (en
debug miro el hilo sobre el q esta funcionando y es el correcto)
asociado al evento de un boton tengo el siguiente codigo:

private void b_aceptar_Click(object sender, System.EventArgs e)
{
ED.debugea("Comenzando volcado de Clientes");
Thread th_aux = new Thread(
new ThreadStart(pv_cuerpothreadactualizacion));
th_aux.Name="Thread auxiliar acutalizacion clientes";
th_aux.IsBackground=true;
th_aux.Priority=ThreadPriority.Lowest;
ED.debugea("Thread padre: "+ Thread.CurrentThread.Name);
b_aceptar.Enabled=false;
th_aux.Start();
/*es te join me bloquea el thread principal en vez del thread de la
ventana hija*/
th_aux.Join();
b_aceptar.Enabled=true;
ED.debugea("Volcado de Clientes Concluido");
}

private void pv_cuerpothreadactualizacion()
{
ED.debugea("Thread hijo: "+ Thread.CurrentThread.Name);
ED.debugea("Delay on");
for (int i = 1; i <= 300; i++) ED.debugea(".");
ED.debugea("Delay off");
}

el metodo cuerpothreadactualizacion solo es un pequeño delay para
comprobar q es lo q se bloquea, cuando esto funcione ahí habrá un codigo
bastante peasado a acceso a bd q costará entre 5 y 10 minutos su
ejecución. Así pues la intencion es poner un medidor de progreso en la
ventana hija mdiy q la ventana mdi principal siga su ejecución puediendo
abrir mas ventanas independientemente.Los metodos de ED.debugea
simpelmente son de debug, escribne en la consola.

La unica solucion q veo es trabajar por paso de mensajes entre threads
en vez de con joins, pero me parece excesivamente complicado.

Gracias.

Kano

pablo crosio wrote:
hola!

basicamente un loop de mensajes es un ciclo que utilizan las aplicaciones
windows para manejar los mensajes recibidos como pueden ser el movimiento del
mouse, una tecla, un click en un menu, etc... esos mensajes dependiendo de
en donde se generen deberan ser tratados por la ventana a la que van
dirigidos... una vez que se cierra la ventana principal manejadora de los
mensajes, el ciclo termina y finalizaria la aplicacion

en C# con Application.Run( ) estas inicializando un ciclo de mensajes

el tema es que estos ciclos de mensajes generalmente se manejan por
threads es decir habria uno por cada thread (aunque no necesariamente)...

lo que yo te proponia era que tuvieras un solo ciclo (un solo
Application.Run()) en el principal... y no por cada hijo
pero vos si o si queres lanzar ventanas hijas en otros threads... y ahi
hasta donde se no te queda otra que generar nuevos loops de mensajes por cada
hijo

la alternativa que te planteaba yo era que lanzaras los hijos desde el
thread principal y solamente utilizaras nuevos threads para los procesos...

lo que no me queda claro es como se duerme el thread principal

tal vez si escribes algo de la logica del proceso podamos darte una ayuda

salu2!!

pablo



email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida