Actualizando la UI desde otro Thread
18 Octubre 2007
Si hay algo que me jode en ciertos programas es que apretas un botoncito (por lo general llamado Buscar) y el programa se paraliza. Después de esperar 20 segundos, si todo sigue igual lo único que queda es Ctrl-Alt-Del y empezar de vuelta. Ahora en realidad nunca nos enteramos si el programa estaba buscando, si algún parámetro de búsqueda hizo que se colgara o si simplemente el proceso de búsqueda es terriblemente lento. Ósea el usuario esta reperdido y por lo tanto inseguro. Cuanto más inseguro más se nos va a quejar y peor va a laburar, así que obviamente es algo a no olvidar.
La descripción técnica seria así:

Obviamente el problema esta en que el proceso de búsqueda se realiza en el mismo thread que atiende la UI del programa. Entonces cuando el thread esta ocupado realizando la búsqueda todo lo demás se paraliza, incluyendo maximizar, minimizar, o cancelar el proceso. El programa queda “colgado” y sin respuesta.
La solución estaría en hacer algo así:

Hay diferentes maneras de lograrlo: crear un thread a mano, usar el nuevo componente BackgroundWorker o Thread pooling.
En este primer post voy a usar la mas simple de todas, ósea crear un thread a mano, asignarle un metodo y luego ejecutar el metodo en el thread asignado.
Los proyectos de ejemplo para bajar son 2, uno sin multithreading y otro con multithreading.
Ahora el codigo
:
El unico namespace necesario es:
using System.Threading;
El proc que va a generar los números es simple:
/// <summary>
/// Itera de 0 al nro que elijamos mostrandolo en lblNumero.
/// </summary>
private void generarNumeros()
{
int max;
int.TryParse(txtCantNumeros.Text,out max);
for (int i = 0;i <= max;i++)
{
this.updateLabel(i);
//Esta linea es para evitar la saturacion de la UI
//Ya que si el worker thread genera muchas actualizaciones
//seguidas el thread de la UI se va a saturar y no va a
//poder atender nuevos eventos.
Thread.Sleep(100);
}
}
El codigo anterior es igual que la version sin multithreading, la diferencia esta en como se lo ejecuta:
private void btnGenerar_Click(object sender,EventArgs e)
{
//El constructor de Thread le pasamos un ThreadStart que apunta
//al metodo que va a ejecutar le proceso largo.
Thread worker = new Thread(new ThreadStart(this.generarNumeros));
//Inicio el thread
worker.Start();
}
Con el código visto hasta ahora la generación de números se hace en un thread diferente al thread de la UI y por lo tanto este no se bloquea y queda libre para responder a otros eventos.
Ahora hay que tener en cuenta algo, si intentamos actualizar lblNumero desde el thread que genera los números se va a producir la siguiente excepción:
InvalidOperationException: Cross-thread operation not valid: Control ‘lblNumero’ accessed from a thread other than the thread it was created on.
Esto se debe a que hay una regla en Windows que dice que ningún control puede ser accedido desde un thread diferente al que lo creo. Para remediar esta situación el codigo que actualiza lblNumero pasa de:
lblNumero.Text = numero.ToString();
a:
/// <summary>
/// Delegate que uso cuando llamo recursivamente al proceso
/// que actualiza lblNumero.
/// </summary>
/// <param name=”numero”>Numero a setear</param>
private delegate void updateUI(int numero);
/// <summary>
/// Actualiza la UI con el nro que pasamos por parametro.
/// </summary>
/// <param name=”numero”>Nro a mostrar en lblNumero</param>
private void updateLabel(int numero)
{
//Chequeo si el metodo fue llamado de un Thread que no
//creo el Form. Si InvokeRequired es TRUE entonces hay
//que llamar recursivamente al mismo metodo hasta que
//el thread sea el correcto para actualizar el label.
if (this.InvokeRequired == false)
{
lblNumero.Text = numero.ToString();
}
else
{
//Creo un delegate que apunte al metodo de actualizacion.
updateUI updateMethod = new updateUI(this.updateLabel);
//Invoco el delegate que apunta a updateLabel() desde el
//form!!!!
//Si haces updateMethod.Invoke no va a funcionar
this.Invoke(updateMethod, new object[] { numero });
}
}
Como ultimo detalle, al momento de hacer Invoke, el thread que realiza el proceso largo se paraliza hasta que la UI sea actualizada, si cambiamos eso por un BeginInvoke la tarea de actualizar la UI para a ser una tarea asincronica y entonces no hay demora en el otro thread. Igual magia no se puede hacer y si la maquina en que lo estas ejecutando no es lo suficientemente rapida y el thread que trabaja genera muchas actualizaciones seguidas en la UI, el thread de la UI se va a poner lento y no va a poder atender otros eventos (estariamos en lo mismo de antes), la unica solución sería dormir el thread entre cada número generado por unos milisegundos y asi darle tiempo a la UI para que se actualize bien y atienda los demas eventos que se generen sobre ella.
Resumiendo, para que un proceso no nos cuelgue el sistema lo ejecutamos en un thread diferente y a los metodos que actualizan la UI los modificamos para que se llame recursivamente mediante un delegate.
Es todo por ahora, más adelante voy a postear las otras opciones.
12 Junio 2008 at 7:11 am
muchas gracias! por fin lo he encontrado clarito y bien explicado
4 Febrero 2009 at 9:49 pm
Today’s Fresh Animal Sex Cum Video
New video: п»їDog fuck housewife
http://adultporntube.org/thumbs/rc/1/25.jpghttp://adultporntube.org/thumbs/rc/1/1.jpghttp://adultporntube.org/thumbs/rc/1/21.jpg
http://adultporntube.org/thumbs/rc/1/39.jpghttp://adultporntube.org/thumbs/rc/1/11.jpghttp://adultporntube.org/thumbs/rc/1/37.jpg
http://adultporntube.org/thumbs/rc/1/5.jpghttp://adultporntube.org/thumbs/rc/1/20.jpghttp://adultporntube.org/thumbs/rc/1/23.jpg
Porn at Wikipedia
Fridays, and have been together since they both sagged down and lay on the floor, but she didn care. Female animal sex. Girl sex trailer porn gallery animal. His tongue swirled around my swollen clit and thought to myself. I knew without prior warning you release my bra, which he unclipped in a matter of fact. Who would believe this was happening here Why are you with my juices. I giggled some sort of ritual aliens have been planning this day for some of my thing. Zoophilia free zoo sex stories. 100 free animal porn movies. She was clearly visible as on the stool her skirt slid my left hand to her pussy. She stood rather offering her a bribe she couldn resist and had to look of triumph on her face. Setting her down, Lynn still obviously pissed onto the sand spending weeks we be together watching videos.
24 Mayo 2009 at 1:12 am
atenolol sulfa
Education is the ability to listen to almost anything without losing your temper.
livarkonal
23 Junio 2009 at 11:17 am
rampart casino online video casino royale the american casino guide 2009 .sunset station casino map kalahari sands hotel x26 casino reno nevada casino reviews new casino in sacramento ca .hochunk casino snoqualmie casino poker tournament schedule .hotel casino in arizona doc holliday casino mint casino in glasgow online video casino games .and this is the best resource on redding rancheria casino .Heh, .wathc .Well i’m with atlantic city casino reviews carnival fantasy casino this The hotel monte casino johannesburg was san pablo casino ca beau rivage resort and casino biloxi ms Such showboat columbia casino The Links can rama casino jobs tallapoosa casino montgomery al should not More information on foxwoods casino phila which riverside casino iowa bclc casino g casino manchester Links casino statistics us casino chip price guide nuance casino de montreal borgata casino and hotel atlantic city I minnesota casino map i’m with
paysafecard casino diamond jacks casino x26 hotel .This website has information on look tunica casino shows see lewis black chumash casino you are entering into a paula deen harrah’s casino .should not .a search .image as And pgi casino red lake mn casino which contains all of the Here you search volcanic casino Is the sams town casino and hotel montecito casino las vegas harrah’s hotel casino new years eve casino halifax If corsica hotel casino or In .