The ConcurrentStack and ConcurrentQueue classes, lock-free and thread-safe implementations of the Stack and Queue classes, build thread safe collections in .Net Thread safe collections were first introduced in .Net 4 with the introduction of the System.Collections.Concurrent namespace. The collection types in the System.Collections.Concurrent namespace contains a collection of thread safe collection classes. ConcurrentStack A stack is a data structure that works on LIFO (last in first out) basis. The ConcurrentStack class is a thread safe counterpart of the generic Stack class. The ConcurrentStack is a thread safe generic collection class that was first introduced as part of .Net Framework 4. Here’s the list of the important methods of this class that illustrate the possible operations. Push(T element) – this method is used to add data of type T. PushRange – this method can be used to add an array of items of type T. TryPop(out T) – this method is used to retrieve the first element from the stack. It returns true on success, false otherwise. TryPeek(out T) – this method is used to retrieve the next element from the stack but it doesn’t remove the element from the stack. Note that similar to the TryPop(out T) method, it returns true on success and false otherwise. TryPopRange – this method is overloaded and works similar to the TryPop but is used for retriving arrays from the stack Here’s how you can create an instance of the ConcurrentStack class and push data to it. ConcurrentStack<Int32> concurrentStack = new ConcurrentStack<Int32>(); for (Int32 index = 0; index < 10; index++) { concurrentStack.Push(index); } To retrieve the elements from out of a concurrent stack, you can leverage the TryPop(out T) method as shown below. Int32 data; bool success = concurrentStack.TryPop(out data); The following code listing illustrates how you can store and retrieve data to and from a concurrent stack. static void Main(string[] args) { ConcurrentStack<Int32> concurrentStack = new ConcurrentStack<Int32>(); for (Int32 index = 0; index < 100; index++) { concurrentStack.Push(index); } while (concurrentStack.Count > 0) { Int32 data; bool success = concurrentStack.TryPop(out data); if (success) { Console.WriteLine(data); } } Console.Read(); } When you execute the above code listing, the numbers 0 to 99 will be displayed in the reverse order at the console window. ConcurrentQueue A queue is a data structure that works on the basis of FIFO (first in first out). The ConcurrentQueue class in .Net acts as a thread safe FIFO based generic queue. The following is the list of the important methods in the ConcurrentQueue class. Enqueue(T element) – this method is used to add an item of type T to the queue TryPeek(out T) – this method is used to retrieve the next element from the queue but it doesn’t remove the element from the queue. This method returns true on success and false when it fails. TryDequeue(out T) – this method is used to retrieve the first element from the queue. Contrary to the TryPeek(out T) method, it removes the element from the queue. This method returns true on success and false otherwise. The following code snippet shows how you can create an instance of the ConcurrentQueue class to store integers. ConcurrentQueue<Int32> concurrentQueue = new ConcurrentQueue<Int32>(); To store elements to the concurrent queue instance you can take advantage of the Enqueue method as shown below. concurrentQueue.Enqueue(100); The following code listing illustrates how you can store and retrieve elements to and from a concurrent queue. ConcurrentQueue<Int32> concurrentQueue = new ConcurrentQueue<Int32>(); for (int index = 0; index < 100; index++) { concurrentQueue.Enqueue(index); } Int32 item; while (concurrentQueue.TryDequeue(out item)) { Console.WriteLine(item); } When you execute the above code listing, the numbers 0 to 99 will be displayed at the console window. Note that both ConcurrentStack and ConcurrentQueue classes are thread safe and they can manage locking and synchronization issues internally. You can also convert the concurrent queue instance to an array by making a call to the ToArray() method. The following code snippet illustrates how this can be achieved. ConcurrentQueue<Int32> concurrentQueue = new ConcurrentQueue<Int32>(); for (Int32 index = 0; index < 100; index++ ) concurrentQueue.Enqueue(index); Int32[] integerArray = concurrentQueue.ToArray(); foreach (int i in integerArray) { Console.WriteLine(i); } The IsEmpty property of the ConcurrentQueue class returns true is the collection is empty, false otherwise. The following code snippet shows how you can use this method. ConcurrentQueue<Int32> concurrentQueue = new ConcurrentQueue<Int32>(); for (Int32 index = 0; index < 100; index++ ) concurrentQueue.Enqueue(index); while(!concurrentQueue.IsEmpty) { Int32 result; concurrentQueue.TryDequeue(out result); Console.WriteLine(result); } Related content how-to How to use FastEndpoints in ASP.NET Core Take advantage of the free open-source FastEndpoints library to build fast and lean APIs in your ASP.NET Core applications. By Joydip Kanjilal Jul 11, 2024 7 mins Microsoft .NET C# Development Libraries and Frameworks how-to How to use Refit to consume APIs in ASP.NET Core Take advantage of Refit REST library to simplify API consumption and make your code cleaner, more efficient, and easier to maintain. By Joydip Kanjilal Jul 04, 2024 10 mins C# Microsoft .NET Software Deployment how-to When to use an abstract class vs. interface in C# Understanding the differences between an abstract class and interface is key to designing loosely coupled and extensible applications. By Joydip Kanjilal Jun 20, 2024 10 mins Small and Medium Business Microsoft .NET C# how-to 6 security best practices for ASP.NET Core Learn the best practices and built-in safeguards for preventing attacks and protecting sensitive data in your ASP.NET Core web applications. By Joydip Kanjilal Jun 07, 2024 6 mins C# Microsoft .NET Web Development Resources Videos