Task Queues in C#: A Complete Guide for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Working with Task Queues in C#: For Beginners

\n\n

In modern development, there is often a need to process many tasks without blocking the main thread of the application. Imagine a web server that must simultaneously respond to hundreds of users, or a background service processing file uploads. In such situations, a task queue comes to the rescue — one of the fundamental data structures and programming patterns.

\n\n

In this article, we will use practical examples to break down how task queues work in C# (.NET), starting from basic classes and ending with thread-safe solutions for multithreaded applications.

\n\n

What is a Task Queue and Why Do You Need It?

\n\n

A Queue is a data structure that operates on the FIFO (First In, First Out) principle: the first added element will be processed first. In the context of tasks, this means we can enqueue a task and process it later when resources become available.

\n\n

Main use cases for task queues:

\n
    \n
  • Background processing (sending emails, generating reports)
  • \n
  • Load balancing (distributing tasks among worker threads)
  • \n
  • Request buffering (when the system cannot process all requests instantly)
  • \n
  • Asynchronous logging (writing logs without slowing down the main application)
  • \n
\n\n

Basic Queue<T> Class in C#

\n\n

In .NET, there is a built-in class Queue<T> from the System.Collections.Generic namespace. Let's look at a simple example:

\n\n
using System;\nusing System.Collections.Generic;\n\npublic class SimpleQueueExample\n{\n    public static void Main()\n    {\n        // Create a queue of strings\n        Queue<string> taskQueue = new Queue<string>();\n\n        // Add tasks\n        taskQueue.Enqueue("Send email to client");\n        taskQueue.Enqueue("Generate report");\n        taskQueue.Enqueue("Update cache");\n\n        Console.WriteLine($"Number of tasks in queue: {taskQueue.Count}");\n\n        // Process tasks in order\n        while (taskQueue.Count > 0)\n        {\n            string task = taskQueue.Dequeue();\n            Console.WriteLine($"Processing: {task}");\n        }\n\n        Console.WriteLine($"Queue is empty: {taskQueue.Count == 0}");\n    }\n}
\n\n

Main methods of Queue<T>:

\n
    \n
  • Enqueue(T item) — adds an element to the end of the queue
  • \n
  • Dequeue() — retrieves and removes an element from the beginning of the queue
  • \n
  • Peek() — returns the first element without removing it
  • \n
  • Count — number of elements in the queue
  • \n
\n\n

Important: Queue<T> is not thread-safe. If multiple threads simultaneously read from and write to the queue, errors will occur. For multithreaded scenarios, use ConcurrentQueue<T>.

\n\n

Thread-Safe Queue: ConcurrentQueue<T>

\n\n

In real-world applications, task queues are almost always used in a multithreaded context. For this, .NET provides ConcurrentQueue<T> from the System.Collections.Concurrent namespace.

\n\n
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        // Task 1: adding elements (Producer)\n        Task producer = Task.Run(() =>\n        {\n            for (int i = 1; i <= 10; i++)\n            {\n                taskQueue.Enqueue($"Task #{i}");\n                Console.WriteLine($"Added task #{i}");\n                

Blogs

Book Recommendations