Concurrencia C#

etSq-1La Concurrencia permite que distintos objetos actúen al mismo tiempo, usando diferentes hilos de control (un solo proceso).

Es decir: Es la propiedad que diferencia a los objetos entre estar activos o no.

Esta la usamos  cuando tenemos que manejar varias acciones diferentes al mismo tiempo, para ello  utilizamos procesos los cuales producen acciones dinámicas independientes dentro de un sistema.

Sabemos hay sistemas los cuales ejecutan en múltiples CPU permitiendo así hilos de control verdaderamente concurrentes, mientras que en los sistemas que ejecutan en un solo CPU sólo se puede conseguir una ilusión de hilos concurrentes de control, normalmente mediante algún algoritmo de tiempo compartido.

 

La mayoría de las veces al diseñar o crear una aplicación en lo último en que se solemos pensar es en si debe o no emplear múltiples hilos para su ejecución; ya que cuando se nos enseña un lenguaje de programación lo que se suele hacer es programar todo dentro del mismo programa principal (el famoso Main( )) sin preocuparnos por nada más !!! :p .

Con el Hardware moderno se debe explotar al máximo las características que este nos ofrece y para ello son las aplicaciones las que se deben encargar de exprimir esos recursos.

¿porqué  utilizar Hilos para ello?

Pues la idea es simple un, Hilo es una especie de proceso muy pequeñito que se va a encargar de ejecutar un mismo trozo de código cada vez que se le diga por tanto consume muy poca memoria RAM y forma parte de un proceso más grande que lo conocemos como programa principal. Básicamente la idea es que el Hilo le ayude al programa principal a hacer su trabajo; por tanto el programa principal debe delegar algunas actividades para que estas sean realizadas por el Hilo.

Explicación:

BackgroundWorker es una clase de ayuda en el espacio de nombres System.ComponentModel para la gestión de un subproceso de trabajo.  Proporciona las siguientes características:

Un modelo de cancelación de cooperación
La capacidad de actualizar de forma segura WPF o controles de Windows Forms cuando el trabajador se completa
Reenvío de excepciones al evento de finalización
Un protocolo para informar sobre el progreso
Una implementación de IComponent lo que le permite estar situado en el diseñador de Visual Studio

Ejemplo:

Explicacion:

  • Establecer la propiedad WorkerReportsProgress true.
  • Periódicamente llamar ReportProgress desde dentro del controlador de eventos DoWork con un valor de “porcentaje completado”, y, opcionalmente, un objeto de estado del usuario.
  • Controlar el evento ProgressChanged, consultar la propiedad ProgressPercentage de su argumento evento.
  • Código en el controlador de eventos ProgressChanged es libre para interactuar con los controles de IU al igual que con RunWorkerCompleted. Esto es por lo general en el que se actualizará una barra de progreso.

Para añadir soporte para la cancelación:

  • Establecer la propiedad WorkerSupportsCancellation true.
  • Compruebe periódicamente la propiedad CancellationPending desde dentro del controlador de eventos DoWork. Si es verdad, ajuste del argumento de evento Cancelar propiedad en true, y volver.
  •  Llamar CancelAsync para solicitar la cancelación.
using System;
using System.Threading;
using System.ComponentModel;

namespace ConsoleApplication1
{
    class Program
    {

        static BackgroundWorker _bw;

        static void Main()
        {
            _bw = new BackgroundWorker
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true
            };
            _bw.DoWork += bw_DoWork;
            _bw.ProgressChanged += bw_ProgressChanged;
            _bw.RunWorkerCompleted += bw_RunWorkerCompleted;

            _bw.RunWorkerAsync("Hola Programador");

            Console.WriteLine("Presiona enter en los proximo 5 segundos para  cancelar");
            Console.ReadLine();
            if (_bw.IsBusy) _bw.CancelAsync();
            Console.ReadLine();
        }

        static void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i <= 100; i += 20)
            {
                if (_bw.CancellationPending) { e.Cancel = true; return; }
                _bw.ReportProgress(i);
                Thread.Sleep(1000);      // Solo por demo...no ira a dormir
            }                         

            e.Result = 123;    //  RunWorkerCompleto
        }

        static void bw_RunWorkerCompleted(object sender,
                                           RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
                Console.WriteLine("Has  cancelado!");
            else if (e.Error != null)
                Console.WriteLine("Error: " + e.Error.ToString());
            else
                Console.WriteLine("Completo: " + e.Result);      // desde DoWork
        }

        static void bw_ProgressChanged(object sender,
                                        ProgressChangedEventArgs e)
        {
            Console.WriteLine("Cargado " + e.ProgressPercentage + "%");
        }
    }
}

El código fuente está disponible en GITHUB clic aquí para descargarlo descarguen la carpeta Concurrencia.

Esto es todo por el momento alguna duda, comentario o sugerencia no duden en escribirme.

 

Comments

Dejar una contestacion

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *