Skip to main content

C# Queues

Introduction

A Queue is a special type of collection that stores elements in a First-In, First-Out (FIFO) order. This means that the first element added to the queue is the first one to be removed. Think of it like waiting in line at a store - the person who arrives first gets served first.

Queues are part of the .NET Collections namespace and are commonly used in scenarios where you need to process items in the exact order they were received, such as:

  • Print job scheduling
  • Message processing systems
  • Request handling in web servers
  • Breadth-first search algorithms
  • Task scheduling

In this tutorial, we'll explore how to create and use the Queue<T> class in C#, understand its key methods, and see practical applications.

Creating a Queue in C#

To work with queues in C#, you need to include the appropriate namespace:

csharp
using System.Collections.Generic;

Basic Queue Creation

You can create a queue in several ways:

csharp
// Creating an empty queue of integers
Queue<int> numbers = new Queue<int>();

// Creating a queue with initial capacity
Queue<string> names = new Queue<string>(capacity: 10);

// Creating a queue from an existing collection
string[] people = { "Alice", "Bob", "Charlie" };
Queue<string> peopleQueue = new Queue<string>(people);

Key Queue Operations

Adding Items to a Queue (Enqueue)

To add an item to a queue, use the Enqueue method:

csharp
Queue<string> customers = new Queue<string>();
customers.Enqueue("Alice");
customers.Enqueue("Bob");
customers.Enqueue("Charlie");

Console.WriteLine($"Number of customers waiting: {customers.Count}");
// Output: Number of customers waiting: 3

Removing Items from a Queue (Dequeue)

To remove and get the item at the front of the queue, use the Dequeue method:

csharp
Queue<string> customers = new Queue<string>();
customers.Enqueue("Alice");
customers.Enqueue("Bob");
customers.Enqueue("Charlie");

string firstCustomer = customers.Dequeue();
Console.WriteLine($"Now serving: {firstCustomer}");
// Output: Now serving: Alice

Console.WriteLine($"Number of customers waiting: {customers.Count}");
// Output: Number of customers waiting: 2

Peeking at Items (Peek)

To view the first item without removing it, use the Peek method:

csharp
Queue<string> customers = new Queue<string>();
customers.Enqueue("Alice");
customers.Enqueue("Bob");

string nextCustomer = customers.Peek();
Console.WriteLine($"Next customer: {nextCustomer}");
// Output: Next customer: Alice

// The queue still contains the same elements
Console.WriteLine($"Number of customers waiting: {customers.Count}");
// Output: Number of customers waiting: 2

Checking if Items Exist (Contains)

To check if an item exists in the queue:

csharp
Queue<string> customers = new Queue<string>();
customers.Enqueue("Alice");
customers.Enqueue("Bob");

bool isBobWaiting = customers.Contains("Bob");
Console.WriteLine($"Is Bob in the queue? {isBobWaiting}");
// Output: Is Bob in the queue? True

bool isCharlieWaiting = customers.Contains("Charlie");
Console.WriteLine($"Is Charlie in the queue? {isCharlieWaiting}");
// Output: Is Charlie in the queue? False

Clearing a Queue

To remove all elements from a queue:

csharp
Queue<string> customers = new Queue<string>();
customers.Enqueue("Alice");
customers.Enqueue("Bob");

Console.WriteLine($"Customers waiting: {customers.Count}");
// Output: Customers waiting: 2

customers.Clear();
Console.WriteLine($"Customers waiting after clearing: {customers.Count}");
// Output: Customers waiting after clearing: 0

Iterating Through a Queue

You can iterate through a queue without modifying it using a foreach loop:

csharp
Queue<string> customers = new Queue<string>();
customers.Enqueue("Alice");
customers.Enqueue("Bob");
customers.Enqueue("Charlie");

Console.WriteLine("Customers in queue:");
foreach (string customer in customers)
{
Console.WriteLine(customer);
}

// Output:
// Customers in queue:
// Alice
// Bob
// Charlie

Note that iterating through a queue does not remove the elements. The queue remains unchanged.

Converting a Queue to an Array

Sometimes you might need to convert a queue to an array:

csharp
Queue<string> customers = new Queue<string>();
customers.Enqueue("Alice");
customers.Enqueue("Bob");
customers.Enqueue("Charlie");

string[] customerArray = customers.ToArray();
Console.WriteLine("Customer array contents:");
foreach (string customer in customerArray)
{
Console.WriteLine(customer);
}

// Output:
// Customer array contents:
// Alice
// Bob
// Charlie

Real-World Applications

Example 1: Print Queue Simulation

This example simulates a print queue where documents are processed in the order they were submitted:

csharp
using System;
using System.Collections.Generic;
using System.Threading;

class PrintJob
{
public string DocumentName { get; }
public int Pages { get; }

public PrintJob(string documentName, int pages)
{
DocumentName = documentName;
Pages = pages;
}
}

class PrinterSimulation
{
public static void Main()
{
Queue<PrintJob> printQueue = new Queue<PrintJob>();

// Add print jobs to queue
printQueue.Enqueue(new PrintJob("Report.pdf", 5));
printQueue.Enqueue(new PrintJob("Invoice.docx", 2));
printQueue.Enqueue(new PrintJob("Presentation.pptx", 15));

Console.WriteLine($"Number of print jobs in queue: {printQueue.Count}");

// Process print jobs
ProcessPrintJobs(printQueue);
}

private static void ProcessPrintJobs(Queue<PrintJob> queue)
{
Console.WriteLine("Starting printer...");

while (queue.Count > 0)
{
PrintJob job = queue.Dequeue();
Console.WriteLine($"Printing: {job.DocumentName} ({job.Pages} pages)");

// Simulate printing time (1 second per page)
for (int i = 1; i <= job.Pages; i++)
{
Console.WriteLine($" Printed page {i} of {job.Pages}");
Thread.Sleep(1000); // Simulate 1 second printing time
}

Console.WriteLine($"Completed: {job.DocumentName}");
Console.WriteLine($"Remaining jobs: {queue.Count}");
}

Console.WriteLine("All print jobs completed.");
}
}

// Output:
// Number of print jobs in queue: 3
// Starting printer...
// Printing: Report.pdf (5 pages)
// Printed page 1 of 5
// ...
// Printed page 5 of 5
// Completed: Report.pdf
// Remaining jobs: 2
// ...
// All print jobs completed.

Example 2: Customer Service System

This example demonstrates a simple customer service system where customers are served in the order they arrived:

csharp
using System;
using System.Collections.Generic;

class CustomerServiceSystem
{
public static void Main()
{
Queue<string> customerQueue = new Queue<string>();
bool running = true;

while (running)
{
Console.WriteLine("\n==== Customer Service System ====");
Console.WriteLine("1. Add customer to queue");
Console.WriteLine("2. Serve next customer");
Console.WriteLine("3. View all waiting customers");
Console.WriteLine("4. Check queue length");
Console.WriteLine("5. Exit");
Console.Write("Select an option: ");

string choice = Console.ReadLine();

switch (choice)
{
case "1":
Console.Write("Enter customer name: ");
string name = Console.ReadLine();
customerQueue.Enqueue(name);
Console.WriteLine($"{name} has been added to the queue.");
break;

case "2":
if (customerQueue.Count > 0)
{
string customer = customerQueue.Dequeue();
Console.WriteLine($"Now serving: {customer}");
}
else
{
Console.WriteLine("No customers in queue.");
}
break;

case "3":
if (customerQueue.Count > 0)
{
Console.WriteLine("\nCustomers waiting:");
int position = 1;
foreach (string customer in customerQueue)
{
Console.WriteLine($"{position}: {customer}");
position++;
}
}
else
{
Console.WriteLine("No customers in queue.");
}
break;

case "4":
Console.WriteLine($"Current queue length: {customerQueue.Count} customers");
break;

case "5":
running = false;
break;

default:
Console.WriteLine("Invalid option. Please try again.");
break;
}
}

Console.WriteLine("Program ended.");
}
}

// Sample interaction:
// ==== Customer Service System ====
// 1. Add customer to queue
// 2. Serve next customer
// 3. View all waiting customers
// 4. Check queue length
// 5. Exit
// Select an option: 1
// Enter customer name: John
// John has been added to the queue.
// ...

Performance Considerations

The Queue<T> class provides efficient operations for its intended purpose:

  • Enqueue and Dequeue operations are O(1) - constant time operations
  • Contains operation is O(n) - it needs to scan through the entire queue
  • Count property is O(1) - constant time
  • Peek is O(1) - constant time

Queue vs. Stack vs. List

OperationQueueStackList
AddEnqueue (at end)Push (at top)Add (at end) or Insert (at index)
RemoveDequeue (from front)Pop (from top)RemoveAt (at index)
AccessPeek (front only)Peek (top only)Direct access by index
OrderFIFO (First In, First Out)LIFO (Last In, First Out)Indexed access

Choose a Queue when you need to process items in the exact order they were received.

Summary

In this tutorial, we explored C# Queues, which implement a First-In, First-Out (FIFO) data structure. We covered:

  • Creating and initializing queues
  • Key operations like Enqueue, Dequeue, and Peek
  • Checking if elements exist in a queue
  • Iterating through a queue
  • Converting queues to arrays
  • Real-world applications like print queues and customer service systems

Queues are essential data structures that help manage data in the order it is received, making them suitable for scenarios where processing order matters.

Practice Exercises

  1. Create a message processing system that adds messages to a queue and processes them one by one.
  2. Implement a breadth-first search algorithm for a simple graph using a queue.
  3. Build a playlist application where songs are played in the order they were added.
  4. Create a simulation of a call center where callers are placed in a queue and answered in order.

Additional Resources

Happy coding with C# Queues!



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)