Trabajo con colas de tareas en C#: para principiantes
\n\nEn el desarrollo moderno, a menudo surge la necesidad de procesar múltiples tareas sin bloquear el hilo principal de la aplicación. Imagina un servidor web que debe responder simultáneamente a cientos de usuarios, o un servicio en segundo plano que procesa la carga de archivos. En tales situaciones, la cola de tareas (task queue) —una de las estructuras de datos y patrones de programación fundamentales— viene al rescate.
\n\nEn este artículo, analizaremos con ejemplos prácticos cómo funcionan las colas de tareas en C# (.NET), comenzando con las clases básicas y terminando con soluciones seguras para subprocesos en aplicaciones multihilo.
\n\n¿Qué es una cola de tareas y para qué sirve?
\n\nUna cola (Queue) es una estructura de datos que funciona según el principio FIFO (First In, First Out): el primer elemento agregado será procesado primero. En el contexto de las tareas, esto significa que podemos poner una tarea en la cola y procesarla más tarde, cuando los recursos estén disponibles.
\n\nEscenarios principales de uso de colas de tareas:
\n- \n
- Procesamiento en segundo plano (envío de correos electrónicos, generación de informes) \n
- Balanceo de carga (distribución de tareas entre hilos de trabajo) \n
- Almacenamiento en búfer de solicitudes (cuando el sistema no puede procesar todas las solicitudes instantáneamente) \n
- Registro asíncrono (escritura de registros sin ralentizar la aplicación principal) \n
Clase básica Queue<T> en C#
\n\nEn .NET existe la clase incorporada Queue<T> del espacio de nombres System.Collections.Generic. Veamos un ejemplo muy simple:
using System;\nusing System.Collections.Generic;\n\npublic class SimpleQueueExample\n{\n public static void Main()\n {\n // Creamos una cola de cadenas\n Queue<string> taskQueue = new Queue<string>();\n\n // Agregamos tareas\n taskQueue.Enqueue("Enviar correo electrónico al cliente");\n taskQueue.Enqueue("Generar informe");\n taskQueue.Enqueue("Actualizar caché");\n\n Console.WriteLine($"Cantidad de tareas en la cola: {taskQueue.Count}");\n\n // Procesamos las tareas en orden\n while (taskQueue.Count > 0)\n {\n string task = taskQueue.Dequeue();\n Console.WriteLine($"Procesando: {task}");\n }\n\n Console.WriteLine($"La cola está vacía: {taskQueue.Count == 0}");\n }\n}\n\nMétodos principales de Queue<T>:
- \n
Enqueue(T item)— agrega un elemento al final de la cola \n Dequeue()— extrae y elimina el elemento del inicio de la cola \n Peek()— devuelve el primer elemento sin eliminarlo \n Count— cantidad de elementos en la cola \n
Importante: Queue<T> no es seguro para subprocesos. Si varios hilos leen y escriben en la cola simultáneamente, se producirán errores. Para escenarios multihilo, usa ConcurrentQueue<T>.
Cola segura para subprocesos: ConcurrentQueue<T>
\n\nEn aplicaciones reales, las colas de tareas casi siempre se usan en un contexto multihilo. Para esto, en .NET existe ConcurrentQueue<T> del espacio de nombres System.Collections.Concurrent.
using System;\nusing System.Collections.Concurrent;\nusing System.Threading.Tasks;\n\npublic class ConcurrentQueueExample\n{\n public static void Main()\n {\n ConcurrentQueue<string> taskQueue = new ConcurrentQueue<string>();\n\n // Tarea 1: agregamos elementos (Producer)\n Task producer = Task.Run(() =>\n {\n for (int i = 1; i <= 10; i++)\n {\n taskQueue.Enqueue($"Tarea #{i}");\n Console.WriteLine($"Agregada tarea #{i}");\n