Threads

17/05/2007 - 19:42 por Robert Barreiro | Informe spam
Mi problema es el siguiente:

Tengo un formulario principal que llama a otro, supongamos form1, el cual
carga unos datos mediante un Stored Procedure. Dicho SP es un poco pesado y
demora unos 5 o 6 segundos en mostrar el formulario con todos los datos. Asi
que decidi crear otra ventanita donde aparece un cartel diciendo "Por favor,
espere..." junto con un GIF animado.

Entonces decidi que debo crear un nuevo Thread en donde corra la nueva
ventanita mientras en el hilo principal se cargan los datos del SP y luego
mato al nuevo hilo creado mediante un hilo.Abort(). Ahora el tema es que la
nueva ventana aparece solo un momento, sin llegar a dibujarse correctamente
y luego de 5 o 6 segundos aparece el formulario con los datos.

En que estoy fallando? Cual seria la forma correcta de encarar este
problema?


Muchas gracias!

Preguntas similare

Leer las respuestas

#1 Alberto Poblacion
17/05/2007 - 20:00 | Informe spam
"Robert Barreiro" wrote in message
news:
Tengo un formulario principal que llama a otro, supongamos form1, el cual
carga unos datos mediante un Stored Procedure. Dicho SP es un poco pesado
y demora unos 5 o 6 segundos en mostrar el formulario con todos los datos.
Asi que decidi crear otra ventanita donde aparece un cartel diciendo "Por
favor, espere..." junto con un GIF animado.

Entonces decidi que debo crear un nuevo Thread en donde corra la nueva
ventanita mientras en el hilo principal se cargan los datos del SP y luego
mato al nuevo hilo creado mediante un hilo.Abort(). Ahora el tema es que
la nueva ventana aparece solo un momento, sin llegar a dibujarse
correctamente y luego de 5 o 6 segundos aparece el formulario con los
datos.

En que estoy fallando? Cual seria la forma correcta de encarar este
problema?



Recuerda que la interface de pantalla es monohilo y que solo se pueden
pintar cosas en pantalla desde el hilo inicial de la misma, de lo contrario
se corrompe o se producen comportamientos extraños (o se genera una
excepción). Si tratas de mostrar algo en un formulario desde otro hilo,
tienes que transportar la ejecución entre hilos mediante el método Invoke de
un Control... y sólo funcionará si el hilo al que transportas la ejecución
no está "pillado" haciendo otra cosa. Así que en tu caso concreto deberías
invertir los papeles, y realizar el acceso a base de datos desde un hilo
separado, mientras que muestras el formulario de espera desde el hilo
principal. Si estás usando el Framework v2.0, el SqlCommand tiene varios
métdos BeginExecuteXxx que automatizan la operación de ejecutarlo en otro
hilo, sin que tengas que preocuparte de manejar el Thread por tu cuenta.
Respuesta Responder a este mensaje
#2 Robert Barreiro
17/05/2007 - 20:46 | Informe spam
Pero...tan complicado es?

Digo, mas alla de la ejecucion del comando sql o lo que fuere, supongamos
que quiero mostrar otra ventanita que aparezca mientras algun proceso se
ejecuta de fondo, sea una consulta sql o el escaneado de archivos de un
directorio. Estem...no hay otra forma mas facil de hacer? Parece algo tan
sencillo y se complica

:(((



"Alberto Poblacion"
escribió en el mensaje news:%
"Robert Barreiro" wrote in message
news:
Tengo un formulario principal que llama a otro, supongamos form1, el cual
carga unos datos mediante un Stored Procedure. Dicho SP es un poco pesado
y demora unos 5 o 6 segundos en mostrar el formulario con todos los
datos. Asi que decidi crear otra ventanita donde aparece un cartel
diciendo "Por favor, espere..." junto con un GIF animado.

Entonces decidi que debo crear un nuevo Thread en donde corra la nueva
ventanita mientras en el hilo principal se cargan los datos del SP y
luego mato al nuevo hilo creado mediante un hilo.Abort(). Ahora el tema
es que la nueva ventana aparece solo un momento, sin llegar a dibujarse
correctamente y luego de 5 o 6 segundos aparece el formulario con los
datos.

En que estoy fallando? Cual seria la forma correcta de encarar este
problema?



Recuerda que la interface de pantalla es monohilo y que solo se pueden
pintar cosas en pantalla desde el hilo inicial de la misma, de lo
contrario se corrompe o se producen comportamientos extraños (o se genera
una excepción). Si tratas de mostrar algo en un formulario desde otro
hilo, tienes que transportar la ejecución entre hilos mediante el método
Invoke de un Control... y sólo funcionará si el hilo al que transportas la
ejecución no está "pillado" haciendo otra cosa. Así que en tu caso
concreto deberías invertir los papeles, y realizar el acceso a base de
datos desde un hilo separado, mientras que muestras el formulario de
espera desde el hilo principal. Si estás usando el Framework v2.0, el
SqlCommand tiene varios métdos BeginExecuteXxx que automatizan la
operación de ejecutarlo en otro hilo, sin que tengas que preocuparte de
manejar el Thread por tu cuenta.

Respuesta Responder a este mensaje
#3 Alberto Poblacion
17/05/2007 - 21:41 | Informe spam
"Robert Barreiro" wrote in message
news:%
Pero...tan complicado es?



Efectivamente. Cuando una serie de procesos que no se diseñaron para
multihilo se intentan usar desde múltiples hilos, se producen toda clase de
conflictos cuando dos hilos intentan manejar simultaneamente una misma
variable que no se encuentra protegida mediante bloqueos contra dicho acceso
múltiple.
Esto es lo que le pasa a la interfase gráfica de los programas Windows:
hereda un diseño antiguo que se basaba en el paso de mensajes, algo que se
denominaba "multitarea cooperativa". El caso es que no está diseñado para
que lo manejen varios hilos. La forma que se ha previsto en .Net para poder
visualizar cosas en un formulario Windows desde varios hilos consiste en que
solo uno de esos hilos pinta las cosas en pantalla, y los otros hilos lo van
"alimentando" para que el principal actúe con los datos que suministran los
otros hilos.

Digo, mas alla de la ejecucion del comando sql o lo que fuere, supongamos
que quiero mostrar otra ventanita que aparezca mientras algun proceso se
ejecuta de fondo, sea una consulta sql o el escaneado de archivos de un
directorio. Estem...no hay otra forma mas facil de hacer? Parece algo tan
sencillo y se complica



No se complica tanto. Creas un hilo que lance en background la tarea que
sea. Después de lanzar esa tarea, muestras la pantalla que quieras. Y si esa
tarea que está en background necesita mostrar algo en pantalla, usa
elFormulario.Invoke(delegado), para llamar indirectamente a través del
delegado a la rutina que pinta en pantalla, en lugar de ejecutar
directamente dicha rutina. Solo hay que intercalar este único paso
intermedio, no es tan complicado.
Respuesta Responder a este mensaje
#4 Robert Barreiro
17/05/2007 - 21:48 | Informe spam
Ahhhh, mira lo que son las vueltas de la vida.

Muchas gracias por tu respuesta y tu tiempo, ha sido de gran ayuda.! :-)



"Alberto Poblacion"
escribió en el mensaje news:
"Robert Barreiro" wrote in message
news:%
Pero...tan complicado es?



Efectivamente. Cuando una serie de procesos que no se diseñaron para
multihilo se intentan usar desde múltiples hilos, se producen toda clase
de conflictos cuando dos hilos intentan manejar simultaneamente una misma
variable que no se encuentra protegida mediante bloqueos contra dicho
acceso múltiple.
Esto es lo que le pasa a la interfase gráfica de los programas Windows:
hereda un diseño antiguo que se basaba en el paso de mensajes, algo que se
denominaba "multitarea cooperativa". El caso es que no está diseñado para
que lo manejen varios hilos. La forma que se ha previsto en .Net para
poder visualizar cosas en un formulario Windows desde varios hilos
consiste en que solo uno de esos hilos pinta las cosas en pantalla, y los
otros hilos lo van "alimentando" para que el principal actúe con los datos
que suministran los otros hilos.

Digo, mas alla de la ejecucion del comando sql o lo que fuere, supongamos
que quiero mostrar otra ventanita que aparezca mientras algun proceso se
ejecuta de fondo, sea una consulta sql o el escaneado de archivos de un
directorio. Estem...no hay otra forma mas facil de hacer? Parece algo tan
sencillo y se complica



No se complica tanto. Creas un hilo que lance en background la tarea
que sea. Después de lanzar esa tarea, muestras la pantalla que quieras. Y
si esa tarea que está en background necesita mostrar algo en pantalla, usa
elFormulario.Invoke(delegado), para llamar indirectamente a través del
delegado a la rutina que pinta en pantalla, en lugar de ejecutar
directamente dicha rutina. Solo hay que intercalar este único paso
intermedio, no es tan complicado.


Respuesta Responder a este mensaje
#5 Robert Barreiro
17/05/2007 - 21:55 | Informe spam
Me falto agregar que finalmente me salio, costo pero quedocon la ayuda
del amigo Alberto y un ejemplo que encontre en
http://www.mycsharpcorner.com/Post.aspx?postID!.

Así que gracias nuevamente!



"Robert Barreiro" escribió en el mensaje
news:
Ahhhh, mira lo que son las vueltas de la vida.

Muchas gracias por tu respuesta y tu tiempo, ha sido de gran ayuda.! :-)



"Alberto Poblacion"
escribió en el mensaje news:
"Robert Barreiro" wrote in message
news:%
Pero...tan complicado es?



Efectivamente. Cuando una serie de procesos que no se diseñaron para
multihilo se intentan usar desde múltiples hilos, se producen toda clase
de conflictos cuando dos hilos intentan manejar simultaneamente una misma
variable que no se encuentra protegida mediante bloqueos contra dicho
acceso múltiple.
Esto es lo que le pasa a la interfase gráfica de los programas
Windows: hereda un diseño antiguo que se basaba en el paso de mensajes,
algo que se denominaba "multitarea cooperativa". El caso es que no está
diseñado para que lo manejen varios hilos. La forma que se ha previsto en
.Net para poder visualizar cosas en un formulario Windows desde varios
hilos consiste en que solo uno de esos hilos pinta las cosas en pantalla,
y los otros hilos lo van "alimentando" para que el principal actúe con
los datos que suministran los otros hilos.

Digo, mas alla de la ejecucion del comando sql o lo que fuere,
supongamos que quiero mostrar otra ventanita que aparezca mientras algun
proceso se ejecuta de fondo, sea una consulta sql o el escaneado de
archivos de un directorio. Estem...no hay otra forma mas facil de hacer?
Parece algo tan sencillo y se complica



No se complica tanto. Creas un hilo que lance en background la tarea
que sea. Después de lanzar esa tarea, muestras la pantalla que quieras. Y
si esa tarea que está en background necesita mostrar algo en pantalla,
usa elFormulario.Invoke(delegado), para llamar indirectamente a través
del delegado a la rutina que pinta en pantalla, en lugar de ejecutar
directamente dicha rutina. Solo hay que intercalar este único paso
intermedio, no es tan complicado.






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