DEV Community

Cover image for Async Task Systems: C# Customer Queue
CatNight A
CatNight A

Posted on

Async Task Systems: C# Customer Queue

I’m currently learning how to build asynchronous task systems with C#.

Instead of jumping directly into Channel<T> or BackgroundService, I started with a much simpler customer queue.

The main thing I learned is that the data structure should follow the business rules.

The Problem

The queue has a few simple rules:

  • Normal customers enter at the end.
  • VIP customers enter at the front.
  • The first customer is processed first.
  • A customer can cancel by ID.

A normal Queue<T> handles customers entering at the end and leaving from the front. It does not fit the VIP rule very well, because VIP customers need to enter at the front.

For this version, I used LinkedList<T> because it gives me access to both ends of the collection.

Customer

public sealed class Customer
{
    public int Id { get; init; }
    public string Name { get; init; } = "";
    public bool IsVip { get; init; }
}
Enter fullscreen mode Exit fullscreen mode

I used an object instead of storing only names because the program needs the customer ID and VIP status later.

A Small Working Example

var queue = new LinkedList<Customer>();

var normalCustomer1 = new Customer
{
    Id = 1,
    Name = "Alice",
    IsVip = false
};

var normalCustomer2 = new Customer
{
    Id = 2,
    Name = "Bob",
    IsVip = false
};

var vipCustomer = new Customer
{
    Id = 3,
    Name = "VIP Customer",
    IsVip = true
};

queue.AddLast(normalCustomer1);
queue.AddLast(normalCustomer2);
queue.AddFirst(vipCustomer);

foreach (Customer customer in queue)
{
    Console.WriteLine(customer.Name);
}
Enter fullscreen mode Exit fullscreen mode

The output is:

VIP Customer
Alice
Bob
Enter fullscreen mode Exit fullscreen mode

This is the basic rule in action:

Normal customer -> the end
VIP customer    -> the front
Enter fullscreen mode Exit fullscreen mode

To add customers through one method:

if (customer.IsVip)
{
    queue.AddFirst(customer);
}
else
{
    queue.AddLast(customer);
}
Enter fullscreen mode Exit fullscreen mode

Processing a Customer

The service processes the first customer and removes it:

if (queue.First is not null)
{
    Customer customer = queue.First.Value;
    queue.RemoveFirst();
    Console.WriteLine($"Processed: {customer.Name}");
}
Enter fullscreen mode Exit fullscreen mode

Cancelling by ID

A cancellation can target the middle of the queue. It is not the same operation as processing the first customer.

var current = queue.First;

while (current is not null)
{
    if (current.Value.Id == customerId)
    {
        queue.Remove(current);
        break;
    }

    current = current.Next;
}
Enter fullscreen mode Exit fullscreen mode

If the ID is not found, the queue should stay unchanged.

Things I Had to Watch

  • Check for an empty queue before removing an item.
  • Reject duplicate IDs and blank names before adding customers.
  • Increase processed or cancelled counts only after success.
  • Test empty queues, duplicate IDs, invalid names, and missing customers.

This version stores everything in memory, so the queue is gone when the program stops. That is fine for now; I want to understand the rules before adding a database or a background worker.

My Current Learning Path

Deque
→ PriorityQueue
→ Task status and retry
→ async/await
→ Channel
→ BackgroundService
→ ASP.NET Core API
→ Persistence and monitoring
Enter fullscreen mode Exit fullscreen mode

The final project will be a more complete asynchronous task system built with C# and .NET. For now, the next step is replacing customer order with task priority using PriorityQueue.

Top comments (3)

Collapse
 
acatnigh profile image
CatNight A •

😘

Collapse
 
technogamerz profile image
𝐓𝐡𝐞 𝐋𝐚𝐳𝐲 𝐆𝐢𝐫𝐥 •

Sorry, 😅 but this emoji always cracks me up. 🤣

Collapse
 
acatnigh profile image
CatNight A •

Haha, same 😀