Introducción

En este post se va a explicar una pequeña introducción al manejo de hilos en C#. Los lenguajes de alto nivel como Java o el propio C# de manera integrada poseen un hilo de ejecución principal, por el cual de manera secuencial se ejecutan todas las líneas de código del programa a través de dicho hilo, que dependiendo del lenguaje puede ser Program, u otro nombre reservado. Esta estructura va a secuenciar todas los métodos, clases, repositorios, etc. que se ejecuten de tal forma que siempre se respete dicha secuencia, toda ubicada en el hilo principal de ejecución. Dependiendo de las circunstancias, podemos llegar a la casuística en la cual necesitemos varios hilos de ejecución simultáneos. Por ejemplo, si quisiésemos ejecutar un método que va a llevar a cabo cálculos muy pesados, o una conexión a una base de datos, y no queremos que el hilo de ejecución principal se quede congelado esperando a que todas las líneas de dicho método sean ejecutadas. Vamos a ver cómo resolver este problema utilizando la clase integrada de C# llamada Thread. Como aclaración, vamos a ver un ejemplo realizado en MVC NetCore 6, pero esta clase se puede utilizar de igual forma en otro tipo de proyectos, como Windows Forms.

Preparando el ejemplo

Primero necesitamos crear un proyecto nuevo en Visual Studio, de tipo MVC NetCore, le vamos a llamar MvcHilos:

Crearemos una carpeta dentro de Views para nuestro ejemplo, llamada Calculadora, con un Index que va a ser una view que pida un número, y en un método post calcule por separado sus múltiplos y potencias. También crearemos el controlador asociado. Finalmente, creamos un modelo llamado ListaNumeros que contendrá dos List<int>, una llamada Múltiplos, y la otra Potencias. Nuestro proyecto debería tener la siguiente estructura:

La view Index tendrá el siguiente formato:

@model ListaNumeros
<h2>Calculadora</h2>


<form method="post">
    <h2>Introduzca un número</h2>
    <input type="number" name="num1" />
   
    <button type="submit">Operar</button>
</form>

@if(Model!=null){


    <div class="container">
        <div class="row">

     <div class ="col-md-6">
                <h2>Potencias</h2>
            @for(int i = 0; i < Model.Potencias.Count; i++)
            {
                <h2> @ViewData["NUMERO"] ^ @i = @Model.Potencias[i] </h2>
            }
     </div>

      <div class="col-md-6">
            <h2>Múltiplos</h2>
            @for (int i = 0; i < Model.Multiplos.Count; i++)
            {
                        <h2> @ViewData["NUMERO"] X @i = @Model.Multiplos[i] </h2>
            }
       </div>

    </div>
    </div>
}

Al principio de la view recibe un modelo de tipo ListaNumeros (que será enviado en el método Post del controller). Posee un form que pide un número al usuario para realizar el método post. Y luego, si el modelo no es nulo, crea dos divs con una columna para las potencias y otra para los múltiplos, almacenados ambos en los atributos Multiplos y Potencias del modelo ListaNumeros.

El siguiente paso es programar el controlador para esta vista. Esta será la primera versión:

namespace MvcHilos.Controllers
{
    public class CalculadoraController : Controller
    {
        public ListaNumeros numeros;
        public CalculadoraController()
        {
            this.numeros = new ListaNumeros();
            this.numeros.Multiplos = new List<int>();
            this.numeros.Potencias = new List<int>();
        }
        
        public ActionResult Index()
        {
            return View();
        }

     

        public void Multiplos(int num1)
        {
      
            for (int i = 0; i < 9; i++)
            {
                this.numeros.Multiplos.Add(num1 * i);
            }
  
        }

        public void Potencias(int num1)
        {
          
            for (int i = 0; i < 9; i++)
            {
                this.numeros.Potencias.Add(1);
                for (int j = 0; j < i; j++)
                {
                    this.numeros.Potencias[i] = this.numeros.Potencias[i] * num1;
                }
            }
        }    
}

El controller posee un constructor que declara a nivel de clase un objeto de tipo ListaNumeros e inicializa sus atributos. El método GET del index devuelve la vista cuando se llame a dicha vista. El método Multiplos va a recibir como parámetro el número introducido por el usuario, y en un bucle for para los 10 primeros múltiplos, va a añadir a la lista de Multiplos de listaNumeros los resultados de operar dicho número por los números del 1 al 10. De igual forma, el método Potencias va a calcular las potencias para los 10 primeros dígitos, creando otro bucle for anidado que dependiendo del valor de i, va a calcular la multiplicación del número por sí mismo tantas veces como se requiera.

Ya tenemos los métodos para realizar los cálculos, ahora nos queda ver cómo implementarlos manejando hilos.

Crear un hilo

Realmente es muy sencillo. La clase Thread ya viene integrada en las librerías del proyecto, por lo que no es necesario importarla. Escribiremos el método Post de la vista index de la siguiente forma:

   [HttpPost]
        public ActionResult Index(int num1)
        {
            ViewData["NUMERO"] = num1;

            Thread hilo1 = new Thread(() => Multiplos(num1));
            Thread hilo2 = new Thread(() => Potencias(num1));

            hilo1.Start();
            hilo2.Start();

            return View(this.numeros);
        }

La clase Thread se inicializa mandándole como parámetro el método que se quiere integrar en dicho hilo. En este caso, como nuestro método tiene un parámetro de entrada (el número dado por el usuario), utilizaremos la función lambda para indicar dicho método. Inicializamos ambos hilos, uno para cada método, y utilizando el método integrado de la clase Thread llamado start(), ambos hilos se ejecutarán de forma síncrona. Una vez ambas ejecuciones hayan terminado, se devolverá a la vista Index el modelo con los valores ya calculados. Finalmente, añadimos un enlace a nuestra vista en el Layout con la siguiente línea y ya podemos ejecutar nuestro programa:

  <li class="nav-item">
   <a class="nav-link text-dark" asp-area="" asp-controller="Calculadora" asp-action="Index">Calculadora</a>
  </li>

Si ejecutamos el programa e introducimos por ejemplo el número 5, el resultado final será el siguiente:

Como ya se explicó en la introducción, este ejemplo tan sólo es una pequeña introducción al manejo de hilos, para entender el concepto de ejecución síncrona. El manejo de hilos incluye muchas más posibilidades, como añadir tiempos de ejecución, control de hilos con semáforos, etc. que ya se explicarán más adelante.

Autor: Sergio Guijarro de Cabo

Curso: Desarrollo Web Full Stack + MultiCloud con Azure y AWS 

Centro: Tajamar 

Año académico: 2022-2023 

Enlace repositoriohttps://github.com/SergioGuijarrodeCabo/MvcHilos.git

Mi Linkedlnwww.linkedin.com/in/sergio-guijarro-de-cabo-a60851146

Leave a Comment

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

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.