C# Concurrent List Tutorial – Complete Guide

In today’s fast-paced world of programming, maintaining data integrity in a multi-threaded environment is no easy task. That’s where C# and its Concurrent Collections come into play, drastically simplifying this challenging task. Among these collections is the powerful Concurrent List.

A Glance at C# Concurrent List

The Concurrent List in C# is a thread-safe version of the List collection. It’s part of the System.Collection.Concurrent namespace and it allows multiple threads to access and manipulate data concurrently without any data inconsistencies and race conditions.

Why Should I Learn About Concurrent List?

Concurrency, especially in game development, could be the difference between a good gaming experience and a great one. Notably, Concurrent List provides an excellent way to manage game entities and their behaviour without fear of inconsistencies and threading issues.

Imagine managing multiple player data, AI entities or even dynamic game environments. A Concurrent List will handle all these concurrently, providing a fluid and bug-free experience to your gamers.

Concurrent List Usage Scenarios

Concurrent List finds its use in scenarios with high concurrency. For instance, massive multiplayer online games (MMOs) where lots of data need to be fetched and updated concurrently. Or, in platformer games with multiple AI entities constantly interacting with the environment.

Now that we’ve covered the basics, let’s dive deeper by writing some C# code in the next sections. Stay tuned!

CTA Small Image
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

Getting Started with Concurrent List in C#

To start, we first need to include the Concurrent namespace in our project:

using System.Collections.Concurrent;

Creating a Concurrent List

Unfortunately, unlike ConcurrentDictionary or ConcurrentQueue, there isn’t a built-in ConcurrentList in .NET. However, we can create our own implementation of it. Here is a basic example:

public class ConcurrentList<T> : IList<T>
{
    private readonly IList<T> _list = new List<T>();
    private readonly object _syncRoot = new object();

    // Define all other IList<T> members here...

    public void Add(T item)
    {
        lock (_syncRoot)
        {
            _list.Add(item);
        }
    }

    // Continue implementing the rest of the IList<T> interface...
}

Adding Elements to the List

Data can be added to the list using the `Add` method:

ConcurrentList<int> list = new ConcurrentList<int>(); 
list.Add(1); 
list.Add(2); 
list.Add(3);

Removing Elements from the List

Removing an element from the List can be achieved using the `Remove` method:

list.Remove(1); // Removes the element '1' from the list

Modifying Elements in the List

For modifying elements, you can access elements in the list like an array and change their value:

list[0] = 4; // Changes the first element of the list to '4'

More amid sketching the basics of a ConcurrentList, crucial is its tangible implementation. We’ll continue this in the next section, where the concurrent aspect of the ConcurrentList will be put forth. Stay tuned!

Thread-Safe Access with Concurrent List

The heart of ConcurrentList’s utility is in its thread-safe nature for access and manipulation of data. By encasing actions in lock statements inside our custom class, we can allow safe, concurrent access from multiple threads.

Implementing Thread-Safe Remove and RemoveAt

public bool Remove(T item)
{
    lock (_syncRoot)
    {
        return _list.Remove(item);
    }
}

public void RemoveAt(int index)
{
    lock (_syncRoot)
    {
        _list.RemoveAt(index);
    }
}

Implementing Thread-Safe Index Access

public T this[int index]
{
    get
    {
        lock (_syncRoot)
        {
            return _list[index];
        }
    }
    set
    {
        lock (_syncRoot)
        {
            _list[index] = value;
        }
    }
}

Enumerable and Collection Functions

While iterating over collections, use the IEnumerable interface and wrap it inside a lock statement:

IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
    return GetEnumeratorTraditional();  
}

public IEnumerator<T> GetEnumeratorTraditional()
{
    lock (_syncRoot)
    {
        return _list.ToList().GetEnumerator();
    }
}

Wrap all ICollection<T> methods as per:

public void Clear()
{
    lock (_syncRoot)
    {
        _list.Clear();
    }
}

public bool Contains(T item)
{
    lock (_syncRoot)
    {
        return _list.Contains(item);
    }
}

This way, our ConcurrentList acts as a regular list with thread safety. By locking shared resources, we ensure only one thread executes the lock statement at any given time, thereby maintaining data integrity and ensuring your software remains free of hard-to-track bugs.

We hope that, through this practical journey into the concept, we’ve made understanding C#’s Concurrent List simpler and enjoyable. Get threading!

Advanced Manipulations

To master the Thread-Safe List, we shall now dive into more complex manipulations including range operations, enumeration and list modification during enumeration.

Range Operations

To add and remove a range of elements, we lock the resource for the duration of the operation:

public void AddRange(IEnumerable<T> items)
{
    lock (_syncRoot)
    {
        foreach (var item in items)
        {
            _list.Add(item);
        }
    }
}

public void RemoveAll(Predicate<T> match)
{
    lock (_syncRoot)
    {
        _list.RemoveAll(match);
    }
}

Thread-Safe Enumeration

During enumeration, the list should be locked to prevent modification. A good practice is to create a copy of the list for enumeration:

public IList<T> GetSnapshot()
{
    lock (_syncRoot)
    {
        return _list.ToList();
    }
}

This can then be used to enumerate the list safely in another thread:

foreach (var element in myList.GetSnapshot())
{
    // Perform operations here...
}

Modifying During Enumeration

While .NET prevents you from modifying a list during enumeration, ConcurrentList, due to the lock statement, allows you to do so.

For instance, you can safely do this (something that would otherwise throw an exception in .NET):

foreach (var item in myList.GetSnapshot())
{
    myList.Remove(item);
}

That’s it: you’ve reached operating adeptness with C#’s Concurrent List! Throughout this tutorial, we’ve laid out the key fundamentals and advanced features necessary to use this valuable collection properly. We hope your journey here encourages you to exploit Concurrent List’s potent features in future projects for efficient and concurrent data manipulations. Happy coding!

Where To Go Next

Having savored a taste of concurrent programming with C#’s Concurrent List, don’t stop here. There’s a plethora of advanced topics out there awaiting your curiosity and learning spirit.

Why not take a step towards game development? We, at Zenva, offer a comprehensive collection of courses through our Unity Game Development Mini-Degree. This Mini-Degree covers a wide array of topics including game mechanics, cinematic cutscenes, audio effects, and more, using one of the world’s most popular game engines – Unity. The skills you can acquire can pave the way for potential opportunities in the thriving game industry.

For a broader learning perspective, delve into our complete Unity Collection. It offers a vast range of modules to help you master the Unity engine.

Zenva Academy provides over 250 supported courses spanning from beginner to professional level. Dive into programming, game development, AI, and much more! Whether you’re just starting or eager to advance your knowledge, Zenva’s flexible, project-based learning enhances your competency and boosts your coding career. Keep expanding, keep creating!

Conclusion

To build robust, efficient software, mastering C#’s Concurrent List is a giant leap forward. With this newfound skill, you’ve unlocked a new dimension of programming, making your code more robust, responsive, and efficient. Not only is this applicable to gaming but also to any genre needing concurrent data access for optimal performance.

Is it time to put your new skills to the test? Delve into projects, explore, and innovate. Our Unity Game Development Mini-Degree is a great way to put your concurrent programming skills to use and build your own stunning game. And remember, the learning journey never ends, so keep pushing, keep coding! We at Zenva are always here to guide you.

Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.