Hay muchas formas de implementar hilos pero la mas sencilla es usando el componente BackgroundWorker este fue introducido desde el framework 2.0 y permite realizas operaciones costosas o duraderas en un hilo diferente al de la interfaz por lo que nuestra aplicación no se vera afectada y continuara respondiendo.
Usando este control, la gestión de hilos está encapsulada en el control de manera que el no tenemos que lidiar con hilos (threads), invokes o delegados (delegates). Que suelen hacer la vida un poco complicada.
Ahora bien se puede usar el componente BackgroundWorker arrastrándolo de la paleta:
El componente tiene 3 funciones para controlar el funcionamiento:
Evento DoWork
Este es invocado cuando se ejecuta le función RunWorkerAsync() en ese momento se genera el segundo hilo de ejecucion; y dado que no es el hilo principal pues la aplicación segira respondiendo como si nada; es decir como lo dice le nombre de la función corre asincronamente por lo que es importante que se tome en cuenta que corre de forma asincrona por lo que el codigo no esperará el aproceso para continuar:
private void button1_Click(object sender, EventArgs e) { progressBar1.Visible = true; backgroundWorker1.RunWorkerAsync(); //este se llama y se ejecuta button1.Enabled = false; //Contiua esta instruccion sin esperar el hilo button2.Enabled = false; }Es importaten señalar cuando estemos codificando el DoWork que tomemos en cuenta que el valor que regresamos queda guardado en la propiedad e.Result el cual podremos invocar despues cuando el proceso este completo; en este ejemplolos uso para regresar el resultado de una consulta ala base dedatos que llega a demorar algún tiempo, y como se ve el resultado de la consulta lo almaceno en e.Result
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { ListqueryResult = db.COMPROBANTE.Where(w => w.C_ENVIO == 0 && w.C_ENVIO != null).ToList();//&& w.CANCELA.Count < 0) var query = queryResult.Select(s => new DataBindingProjection { ID = s.C_ID, Cliente = s.RECEPTOR.R_NOMBRE, Correo = s.RECEPTOR.R_CORREO, SERIE = s.C_SERIE, FOLIO = s.C_FOLIO, FolioFiscal = s.C_FOLIOFISCAL, SubTotal = s.C_SUBTOTAL, Iva = s.C_IVA, Total = s.C_TOTAL, Saldo = decimal.Round((decimal)s.C_SALDO, 2), TIPOCAMBIO = s.C_TIPOCAMBIO, Moneda = s.C_TIPOCAMBIO == 1 ? "MXN" : "USD", FechaEmicion = s.C_FECHA, FechaVencimiento = s.C_VENCIMIETO } ).OrderBy(o=>o.SERIE).ThenBy(o=>o.FOLIO).ToList(); e.Result = query.ToList();//regresa el arreglo oque voy a desplegar }
Evento ProgressChanged
Este evento es lanzado en el hilo principal, por lo que aquí SI podemos acceder a controles del formulario de manera segura.private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; //actualizamos la barra de progreso }
Evento RunWorkerCompleted
Este método se ejecuta cuando la el proceso ha concuido junto con el hilo de ejecuciony solo peude ser por 3 medio:
- El proceso termina de forma normal sin errores ni cancelaciones
- El proceso termina debido a un error durante su ejecucion
- Cancelado por el usuario/programador
En el objeto RunWorkerCompletedEventArgs nos brinda la información de como es que se completo el hilo y asi saber como trabajar con el valor de la propiedad Result,
private void backgroundWorker1_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e) { if (e.Cancelled) { MessageBox.Show("La tarea fue cancelada"); } else if (e.Error != null) { MessageBox.Show("Setermino con error: " + (e.Error as Exception).ToString()); } else { MessageBox.Show("La busqueda a concluido "); if (e.Result != null) { dataGridView1.DataSource = e.Result; progressBar1.Visible = false; button1.Enabled = true; button2.Enabled = true; } } }
Enviado las órdenes de cancelación al control.
Por ultimo pero no menos importante como podemos cancelar el proceso una ves que ha sido lanzado? pues es facil solo se invoca la funcion CancelAsync() y el proceso terminará
private void btoCancel_Click(object sender, EventArgs e)
{
backgroundWorker1.CancelAsync();
}
En fin creo que eso es todo ojala les resulte útil is tienen dudas pregunten abajo...