Autor Tema: .Net, Procesos en segundo plano  (Leído 4487 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado tekun

  • -^- Elite Silver -^-
  • The Communiter-
  • *
  • Mensajes: 3221
  • Han convertido mi casa en cueva de mercaderes!!!!
    • www.tekun.es
.Net, Procesos en segundo plano
« : abril 04, 2008, 01:13:43 pm »
bueno, tengo un proceso que se tarda un pelin en .Net, es una rutina que llena un listview, lo he puesto en el evento shown, que supuestamente es el ultimo en cargarse, pero aun no se dibuja todo el form... el efecto que quiero eliminar es que no se vea como "pegado" el proceso....

es decir que no se termina de dibujar el form hasta que esta lleno el listview... es posible hacer lo que necesito?¿?¿ que se vea el efecto que crece la barra de desplazamiento y que se pueda en los otros controles del en el form (botones, textbox, etc...)sin ningún problema....?¿?¿¿?
lo difícil lo hago rápido, con lo imposible, casi siempre me tardo un poquito

Desconectado Juancho

  • The Communiter-
  • *
  • Mensajes: 1311
Re: .Net, Procesos en segundo plano
« Respuesta #1 : abril 04, 2008, 02:38:41 pm »
Vaia si en tu caso lo q necesita es utilizar o cargar el grid en segundo plano, y eso es muy sencillo con el control BackgroundWorker que incluye el VS2005.

Lo q pasa q siemrpe q se ejectun tarearr muy largas y se ponen en el evento LOAD de un formulario siempre vas a ver como cortado o como q no c a terminado d cargar. Entonces al utilizar el BW, podes si queres poner una animacion de cargando mientras hace una operacion o algo en segundo plano.

El control BW tiene une evento que se llama DOWORK, en el cual en este evento vamos a agregar todo lo q necesita hacer mi programa para llenar el grid, digamos en este caso abrir la BD, Cargar la tabla y despues pasarla al grid, X ejemplo:

Private sub BW_DoWork()
    Dim Tabla as new datatable
    'Se hacen las operaciones que sean necesarias y al final se tiene q conectar la tabla con el grid entonces te quedaria asi:
    datagridview.datasource = tabla
end sub

Y d alli en el evento LOAD del formulario para ejecutar este procedimiento agrregas una linea que seria:

BW.RunWorkerAsync()

Y de esa manera con esa linea significa q t va a empezar a ejecutar el evento DoWork en segundo plano.
Cuando el procedimiento llegue a su fin, el control tiene otro evento llamado RunWorkerCompleted (creo q asi es jejeje) entonces ese evento te indica que el procedimiento en segundo plano finalizo. Digamos en tu caso cuando se esta cargando habias puesto un tierm con una animacion de cargando entonces en ese evento podrias detener el timer porque significa q ya se cargo todo.

COSAS IMPORTANTE QUE HAY QUE TENER ENCUENTA AL REALIZAR OPERACIONES EN SEGUNDO PLANO:
  - NO podes escribir ya sea en un control directamen en el evento DoWork, xq VS2005 te va a mandar un error diciendot que no podes accesar a ese elemento porque fue creado en otro hilo disitno al que lo esta ejecutando, por tanto como seguridad de VS2005 sirve para q no se pueda acceder a un control desde 2 o mas hilos a la vez! Entonces como el ejemplo q t puse arriva la linea de codigo "datagridview.datasource = tabla" nos  daria error, entonces existe una solucion y esa t la da la ayuda MSDN.

Creas un procedimiento que se encargue uinicamente de hacer esa conexion con el grid: entonce digamos que le pones a nuestro procedimiento Carga_grid y a la vez creamos un delegado para poder ejectuar ese procedimiento. Por tanto primero creamos el delegado:

Delegate Sub delg_ConectarGrid(Tbl as datatable)

Y luego nuestro procedimiento CargaGrid, nos quedaria de la siguiente manera:

Private Sub Carga_grid(Tbl as datatable)
    'El formulario incluye una propiedad que se llama InvokeRequerid (creo q asi c escribe) y lo q hace esta propiedad es verificar si se esta llamando
    'a este procedimiento desde otro hilo que no sea el de la aplicacion principal, entonces eso es lo q necesitamos saber, Si es true significa q desd   
    'otro procedimeinto se esta llamando y por tanto ejecutamos de nuevo este proceso por medio de un delegado
    if me.invokerequerid then
        Dim Po as new delg_ConectarGrid(addreesof Carga_Grid)
        'ya tenemos instanciado nuestro delegado con direccion nuevamente, apuntando a este proceso, entonce para ejectuar un delegado los
        'form incluyen una funcion Invoke entonces la utilizamos para que desde el form ejecutemos el delegado y asi ya no tengamos problemas de
        'que estamnos intentando acceder al control desde otro HILO que no fue el que lo creo
        me.invoke(po, tbl)  'Despues del delegado le pasamos el parameotr que en este caso seria la tabla
   else
        'Si no hay problemas en lo de los hilos hoy si ya sin ningun problemas ya podemos conetcar la tabla con el grid
        datagridview.datasource = tbl
   end if
end sub

Entonce por ultimo nos tocaria modificar la linea de codigo del evento DoWork y nos quedaria asi:

Private sub BW_DoWork()
    Dim Tabla as new datatable
    'Se hacen las operaciones que sean necesarias y al final se tiene q conectar la tabla con el grid entonces te quedaria asi:
    Carga_grid(tabla)
end sub

Y allil lo tendrias. Cualquier duda m avisas o la pones intent ser lo mas claro en la explicaion pero si no m entendistes lo de InvokeRequerid t podes leer un poquito mas en la ayuda. Cualquier onda m avisas!




   

<a href="http://www.gametracker.com/player/%7BAiPI%7DJuancho/94.127.17.72:11480/" target="_blank">
<img src="http://cache.www.gametracker.com/player/%7BAiPI%7DJuancho/94.127.17.72:11480/b_560x95.png" border="0" width="560" height="95" alt="" />
</a>