Trabajo con colas de tareas en C#: guía completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course
```html

Introducción a las colas de tareas en C#



En la programación multiproceso moderna, la cola de tareas (task queue) es un patrón fundamental para organizar el procesamiento asíncrono de datos. En C# (.NET), este patrón se implementa a través de varios mecanismos potentes que permiten a los desarrolladores gestionar eficientemente los hilos de ejecución y distribuir la carga de trabajo.



La cola de tareas resuelve el problema clásico de productor-consumidor (producer-consumer), donde una parte del código crea tareas y otra las procesa. En este artículo, exploraremos las principales formas de implementar colas de tareas en C#: desde colecciones simples hasta canales modernos (Channel).



Enfoques principales para implementar colas de tareas



1. ConcurrentQueue — cola thread-safe



La implementación más simple y de bajo nivel es ConcurrentQueue<T> del espacio de nombres System.Collections.Concurrent. Proporciona los métodos thread-safe Enqueue y TryDequeue.



using System;using System.Collections.Concurrent;using System.Threading.Tasks;

public class SimpleTaskQueue{ private readonly ConcurrentQueue<Action> _tasks = new(); private readonly Task _worker;

public SimpleTaskQueue() { _worker = Task.Run(ProcessTasks); }

public void Enqueue(Action task) { _tasks.Enqueue(task); }

private void ProcessTasks() { while (true) { if (_tasks.TryDequeue(out var task)) { task(); } } }}


Ventajas:

  • Simplicidad de uso
  • Bajo consumo de memoria
  • Thread-safe sin bloqueos


Desventajas:

  • Espera activa (busy waiting) en el bucle
  • Falta de señalización sobre nuevas tareas
  • Dificultad para detenerlo


2. BlockingCollection — cola con bloqueo



BlockingCollection<T> resuelve el problema de la espera activa. Proporciona los métodos Add y Take, que bloquean el hilo hasta que aparezcan datos.



using System;using System.Collections.Concurrent;using System.Threading.Tasks;

public class BlockingTaskQueue : IDisposable{ private readonly BlockingCollection<Action> _tasks = new(new ConcurrentQueue<Action>()); private readonly Task[] _workers; private bool _disposed;

public BlockingTaskQueue(int workerCount = 4) { _workers = new Task[workerCount]; for (int i = 0; i < workerCount; i++) { _workers[i] = Task.Run(ProcessTasks); } }

public void Enqueue(Action task) { _tasks.Add(task); }

private void ProcessTasks() { foreach (var task in _tasks.GetConsumingEnumerable()) { if (_disposed) break; task(); } }

public void CompleteAdding() { _tasks.CompleteAdding(); }

public void Dispose() { _disposed = true; _tasks.CompleteAdding(); Task.WaitAll(_workers); _tasks.Dispose(); }}


Características clave:

  • Bloqueo automático del hilo cuando no hay tareas
  • Soporte para cancelación mediante CancellationToken
  • Posibilidad de limitar la capacidad de la cola
  • Finalización segura mediante CompleteAdding


Enfoque moderno: Channel<T>



A partir de .NET Core 3.0 y .NET 5, en C# apareció System.Threading.Channels.Channel<T> — esta es la implementación más eficiente y flexible de una cola de tareas. Soporta operaciones asíncronas, cancelación y limitación del rendimiento.

```

Blogs

Book Recommendations