HILOS EN C# - PARTE I

El concepto de Hilos o Threading no es un tema desconocido para la gran mayoría de programadores con experiencia, pero hago este tutorial de hilos para c# tratando de explicar lo más fácil posible su uso, y lo más importante. Para qué y cuando usarlos

¿QUÉ ES UN HILO (Thread)?

Un hilo se define como la ruta de ejecución de un programa. Cada hilo define un flujo único de control. Si su aplicación implica operaciones complicadas y que requieren mucho tiempo, entonces a menudo es útil para establecer diferentes rutas de ejecución o hilos, con cada hilo de la realización de un trabajo en particular.

Los hilos son procesos ligeros. Un ejemplo común de uso de hilo es la implementación de la programación concurrente por los sistemas operativos modernos. El uso de hilos ahorra desperdicio de ciclo de la CPU y aumentar la eficiencia de una aplicación.

Hasta ahora hemos escrito los programas en los que un solo hilo ejecuta como un proceso único, que es la instancia en ejecución de la aplicación. Sin embargo, de esta manera la aplicación puede realizar una tarea a la vez. Para hacerlo ejecutar más de una tarea a la vez, podría dividirse en las discusiones más pequeñas.

CICLO DE VIDA DE UN HILO (Thread)

El ciclo de vida de un hilo comienza cuando se crea un objeto de la clase System.Threading.Thread y termina cuando el hilo se termina o finaliza la ejecución.

A continuación se presentan los diferentes estados del ciclo de vida de un hilo:

  • Unstarted State: Es la situación en la que se crea la instancia de la Thread, pero el método de inicio no se llama.
  • Ready State: Es la situación en la que el hilo está listo para funcionar y esperando ciclo de la CPU.
  • Not Runnable State: Un hilo no es ejecutable, cuando:
    • Sleep method has been called
    • Wait method has been called
    • Blocked by I/O operations
  • The Dead State: Es la situación cuando el hilo completa la ejecución o se aborta.

EL HILO PRINCIPAL

En C #, la clase System.Threading.Thread se utiliza para trabajar con hilos. Permite crear y acceder a hilos individuales en una aplicación multiproceso. El primer hilo que se ejecutará en un proceso se llama el hilo principal.

Cuando un programa en C # comienza la ejecución, se crea automáticamente el hilo principal. Los hilos creados con la clase Thread son llamados los niños hilos del hilo principal. Se puede acceder a un hilo mediante la propiedad CurrentThread de la clase Thread.

El programa siguiente muestra la ejecución hilo principal:


Cuando se compila el código anterior y ejecutado, se produce el siguiente resultado:

PROPIEDADES Y METODOS DE LA CLASE THREAD



La siguiente tabla muestra algunas de las propiedades más utilizadas de la clase Thread:

PropiedadesDescripción
CurrentContextObtiene el contexto actual en el que el hilo se está ejecutando.
CurrentCultureObtiene o establece la cultura para el subproceso actual.
CurrentPrincipleObtiene o establece director actual de la rosca (para la seguridad basada en roles).
CurrentThreadObtiene el hilo en ejecución.
CurrentUICultureObtiene o establece la cultura actual que utiliza el Administrador de recursos para buscar los recursos específicos de la cultura en tiempo de ejecución.
ExecutionContextObtiene un objeto ExecutionContext que contiene información sobre los diversos contextos de la hebra actual.
IsAliveObtiene un valor que indica el estado de ejecución del subproceso actual.
IsBackgroundObtiene o establece un valor que indica si un hilo es un hilo de fondo.
IsThreadPoolThreadObtiene un valor que indica si es o no un hilo pertenece al grupo de subprocesos administrado.
ManagedThreadIdObtiene un identificador único para el subproceso administrado actual.
NameObtiene o establece el nombre del hilo.
PriorityObtiene o establece un valor que indica la prioridad de planificación de un hilo.
ThreadStateObtiene un valor que contiene los estados de la hebra actual.


La siguiente tabla muestra algunos de los métodos más utilizados de la clase Thread:

Sr.No.Methods
1public void Abort()
Plantea una ThreadAbortException en el hilo en el que se invoca, para iniciar el proceso de terminación de la rosca. Al llamar a este método por lo general termina el hilo.
2public static LocalDataStoreSlot AllocateDataSlot()
Asigna una ranura de datos sin nombre en todos los hilos. Para un mejor rendimiento, los campos de uso que están marcados con el ThreadStaticAttribute atribuyen su lugar.
3public static LocalDataStoreSlot AllocateNamedDataSlot(string name)
Asigna una ranura de datos cuyo nombre aparece en todas las discusiones. Para un mejor rendimiento, los campos de uso que están marcados con el ThreadStaticAttribute atribuyen su lugar.
4public static void BeginCriticalRegion()
Notifica a un anfitrión que la ejecución está a punto de entrar en una región de código en el que los efectos de un hilo abortan o excepción no controlada pueda poner en peligro otras tareas en el dominio de aplicación.
5public static void BeginThreadAffinity()
Notifica a un anfitrión que logró código está a punto de ejecutar las instrucciones que dependen de la identidad del subproceso actual sistema operativo físico.
6public static void EndCriticalRegion()
Notifica a un anfitrión que la ejecución está a punto de entrar en una región de código en el que los efectos de un hilo abortan o excepción no controlada se limitan a la tarea actual.
7public static void EndThreadAffinity()
Notifica a un anfitrión que logró código ha terminado de ejecutar las instrucciones que dependen de la identidad del subproceso actual sistema operativo físico.
8public static void FreeNamedDataSlot(string name)
Elimina la asociación entre un nombre y una ranura, para todos los subprocesos del proceso. Para un mejor rendimiento, los campos de uso que están marcados con el ThreadStaticAttribute atribuyen su lugar.
9public static Object GetData(LocalDataStoreSlot slot)
Recupera el valor de la ranura especificado en el subproceso actual, dentro del dominio actual del subproceso actual. Para un mejor rendimiento, los campos de uso que están marcados con el ThreadStaticAttribute atribuyen su lugar.
10public static AppDomain GetDomain()
Devuelve el dominio actual en el que se está ejecutando el subproceso actual.
11public static AppDomain GetDomain()
Devuelve un identificador de dominio de aplicación única
12public static LocalDataStoreSlot GetNamedDataSlot(string name)
Parece una ranura de datos con nombre. Para un mejor rendimiento, los campos de uso que están marcados con el ThreadStaticAttribute atribuyen su lugar.
13public void Interrupt()
Interrumpe un hilo que está en el estado de rosca WaitSleepJoin.
14public void Join()
Bloquea el subproceso de llamada hasta que un subproceso termina, sin dejar de realizar COM estándar y bombeo SendMessage. Este método tiene diferentes formas sobrecargados.
15public static void MemoryBarrier()
Sincroniza acceso a la memoria de la siguiente manera: El procesador que ejecuta el subproceso actual no se puede cambiar el orden de las instrucciones de tal forma que los accesos a memoria antes de la llamada a MemoryBarrier ejecutar después de accesos a memoria que siguen la llamada a MemoryBarrier.
16public static void ResetAbort()
Cancela una Abortar solicitó para el subproceso actual.
17public static void SetData(LocalDataStoreSlot slot, Object data)
Establece los datos en la ranura especificada en la rosca actualmente en ejecución, para el dominio actual de ese hilo. Para un mejor rendimiento, los campos marcados con el uso del ThreadStaticAttribute atribuyen su lugar.
18public void Start()
Inicia un hilo.
19public static void Sleep(int millisecondsTimeout)
Hace la pausa tema por un período de tiempo.
20public static void SpinWait(int iterations)
Causas de un hilo que esperar el número de veces definido por el parámetro de iteraciones
21
public static byte VolatileRead(ref byte address)
public static double VolatileRead(ref double address)
public static int VolatileRead(ref int address)
public static Object VolatileRead(ref Object address)
Lee el valor de un campo. El valor es el último escrito por cualquier procesador de una computadora, sin importar el número de procesadores o el estado de la caché del procesador. Este método tiene diferentes formas sobrecargados. Sólo algunos se dan arriba.
22
public static void VolatileWrite(ref byte address,byte value)
public static void VolatileWrite(ref double address, double value)
public static void VolatileWrite(ref int address, int value)
public static void VolatileWrite(ref Object address, Object value)
Escribe un valor en un campo inmediato, por lo que el valor es visible para todos los procesadores del ordenador. Este método tiene diferentes formas sobrecargados. Sólo algunos se dan arriba.
23public static bool Yield()
Hace que el hilo de llamar para obtener la ejecución a otro hilo que está listo para ejecutarse en el procesador actual. El sistema operativo selecciona el hilo a ceder a.

CREANDO THREADS

Los hilos se crean mediante la ampliación de la clase Thread. La clase Thread extendida continuación, llama al método Start () para iniciar la ejecución del hilo hijo.
El siguiente programa demuestra el concepto:
  

Cuando se compila el código anterior y ejecutado, se produce el siguiente resultado:

ADMINISTRANDO THREADS

La clase Thread proporciona varios métodos para la gestión de las discusiones.

El siguiente ejemplo muestra el uso del método sleep () para hacer una pausa tema por un período específico de tiempo.





Cuando se compila el código anterior y ejecutado, se produce el siguiente resultado:




DESTRUYENDO THREADS

El método Abort () se usa para destruir las roscas.

El tiempo de ejecución se interrumpe el hilo lanzando un ThreadAbortException. Esta excepción no puede ser capturado, el control se envía al bloque finally, si existe.

El siguiente programa ilustra esto:
Cuando se compila el código anterior y ejecutado, se produce el siguiente resultado:


EJECUTANDO VARIOS HILOS(THREADS)



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace Varios_procesos_csharp
{
    class Program
    {
        static void Main(string[] args)
        {
            ThreadStart iniciando_hilo_01 = new ThreadStart(new Program().procesos_01);
            ThreadStart iniciando_hilo_02  = new ThreadStart(new Program().procesos_02);
            ThreadStart iniciando_hilo_03    = new ThreadStart(new Program().procesos_03);

            Thread[] hilo = new Thread[3];
            hilo[0] = new Thread(iniciando_hilo_01);
            hilo[1] = new Thread(iniciando_hilo_02);
            hilo[2] = new Thread(iniciando_hilo_03);

           
            for (int i = 0; i < hilo.Length; i++)
            {
             
                hilo[i].Start();
                Console.WriteLine("=====================================================");
                Console.WriteLine("EJECUTANDO EL PROCESO" + i);
             
                Console.WriteLine("=====================================================");
                Thread.Sleep(2000);
            }

            Console.ReadLine();
        }

        public void procesos_01()
        {
            //EJECUTANDO EL PRIMER PROCESO
            for (int x = 0; x < 50; x++)
            {
                if (x % 2 ==0)
                {
                    Console.WriteLine("NUMERO PAR {0}",x);
                }
            }
        }

        public void procesos_02 ()
        {
           int [,] datos = new int[5,5];
         
            for (int fila = 0; fila < 5; fila++)
{
             
                for (int col = 0; col < 5; col++)
   {

                    datos[fila, col] = (fila * col) * 10;
   }

}
            for (int fila = 0; fila < 5; fila++)
            {

                for (int col = 0; col < 5; col++)
                {

                    Console.Write(datos[fila, col]);
                }
                Console.WriteLine();
            }


        }
        public void procesos_03()
        {

            string[] platos = { "CHAUFA", "TALLARIN", "POLLO A LA BRAZA", "ARROZ CON POLLO" };
            for (int x = 0; x < platos.Length; x++)
            {
                Console.WriteLine(platos[x]);
            }
        }
    }
}





No hay comentarios:

Publicar un comentario