---
title: "Concurrent Collections in C#"  
description: "Traditional collection classes are using with a lock, but concurrent collection classes are lock free. So, it will often use in parallel programming f"  
author: "Anupam Mishra"  
published: 2016-01-23  
updated: 2020-08-10  
canonical: https://www.mindstick.com/articles/11985/concurrent-collections-in-c-sharp  
category: "c#"  
tags: ["c#", ".net"]  
reading_time: 3 minutes  

---

# Concurrent Collections in C#

In C#, traditional collection classes are using with a lock, but concurrent collection classes are lock free. So, it will often use in parallel programming for performance concern. [ConcurrentDictionary](https://www.mindstick.com/forum/162007/what-is-concurrentdictionary-why-use-it-in-programming-with-proc-and-cons) runs three times faster than Dictionary.

The concurrent collections can sometimes be useful in general multithreading when we need a thread-safe collection. However, there are some conditions:

- The concurrent collections are using in highly concurrent scenarios.
- A thread-safe collection doesn’t guarantee that the code using it will be thread-safe.
- If we enumerate over a concurrent collection while another thread is modifying
- it, no exception is thrown.
- There’s no concurrent version of List<T> in concurrent collections.
- The concurrent stack, queue, and bag classes are implemented internally with
- linked lists.

In Framework 4.0 provides a set of new collections in the

System.Collections.Concurrent namespace. All of these are fully thread-safe:

· ConcurrentStack<T>

· ConcurrentQueue<T>

· ConcurrentBag<T>

· BlockingCollection<T>

· ConcurrentDictionary<Tkey,TValue>

\

IProducerConsumerCollection<T>

In the IProducerConsumerCollection<T> interface defines methods to manipulate

thread-safe collections intended for producer/consumer usage. A

producer/consumer collections which is the two primary use cases. These are:

- Adding an element (“producing”)
- Retrieving an element (“consuming”)

The IProducerConsumerCollection<T> interface are implementing three classes

these are follows:

##### ConcurrentStack<T>

##### \
ConcurrentQueue<T>

##### \
ConcurrentBag<T>

\
This interface also extends ICollection interface for adding the following methods:\

##### bool TryAdd (T item);

##### \
bool TryTake (out T item);

The TryAdd and TryTake methods test [add and remove](https://www.mindstick.com/forum/160516/how-to-add-and-remove-a-column-in-datatable-in-dot-net-using-c-sharp) operation for eliminating

\

the need of lock. If the collection is empty TryTake returns false otherwise, TryAdd

\

always succeeds and returns true.

\

##### ConcurrentBag<T>

ConcurrentBag<T> stores an unordered collection of objects (it allows duplicates contents). ConcurrentBag<T> is prefer in situations when we do not care which element we get when calling TryTake or Take.

The benefit of ConcurrentBag<T> over a concurrent queue or stack is that a bag’s Add method suffers almost no contention when called by many threads at once. A concurrent bag would be a poor choice for a producer/consumer queue, because elements are added and removed by different threads.

##### BlockingCollection<T>

If we call TryTake on any of the producer/consumer collections we discussed previously and the collection is empty, the [method returns](https://www.mindstick.com/forum/12904/main-method-returns-if-submethod-has-stoped-by-return-in-c-sharp) false. Sometimes it would be more useful in this scenario to wait until an element is available. Rather than overloading the TryTake methods

Here we use BlockingCollection<T> ([exception handling](https://www.mindstick.com/articles/12240/introduction-of-exception-handling) aside) in a program:

```
class AddTakeDemo{  
public static void BC_AddTakeCompleteAdding()  
{     
using (BlockingCollection<string> bc = new BlockingCollection<string>())       
{            // Spin up a Task to populate the BlockingCollection             using (Task t1 = Task.Factory.StartNew(() =>            {                for (int i = 1; i <=10; i++)                {                    bc.Add("HI Guest "+i);                }                bc.CompleteAdding();            }))            {                // Spin up a Task to consume the BlockingCollection                using (Task t2 = Task.Factory.StartNew(() =>                {                    try                    {                        // Consume consume the BlockingCollection                        while (true) Console.WriteLine(bc.Take());                    }                    catch (InvalidOperationException)                    {                        // An InvalidOperationException means that Take() was called on a completed
                            collection                        Console.WriteLine("That's All. Everything is Ok!");                    }                }))                    Task.WaitAll(t1, t2);            }  
}   
}}class BlockingCollectionEx{   
static void Main()
{  
    Console.WriteLine(@" Let's try to use Concurrent collection");   AddTakeDemo.BC_AddTakeCompleteAdding();      
   Console.ReadKey();   
}}
```

##### \
Output:

\

**![Concurrent Collections in C#](https://www.mindstick.com/mindstickarticle/e61afc81-9e6d-417d-8544-84d57b43a763/images/3c6d1d94-cc7e-4a0b-9cc3-eac687f391ae.png)**

Because we didn’t pass anything into Blocking Collection’s constructor, it instantiated a concurrent queue automatically.

##### For details we see also:

##### · [Parallel Programming in C#](https://www.mindstick.com/Articles/11980/parallel-programming-in-c-sharp)

##### · [Synchronization in C#](https://www.mindstick.com/Articles/11983/synchronization-in-c-sharp)

##### · [https://msdn.microsoft.com/en-us/library/dd287147%28v=vs.110%29.aspx](https://msdn.microsoft.com/en-us/library/dd287147%28v=vs.110%29.aspx)

##### · [https://msdn.microsoft.com/en-us/library/dd267331%28v=vs.110%29.aspx](https://msdn.microsoft.com/en-us/library/dd267331%28v=vs.110%29.aspx)

##### \
· [https://msdn.microsoft.com/en-us/library/dd381779%28v=vs.110%29.aspx](https://msdn.microsoft.com/en-us/library/dd381779%28v=vs.110%29.aspx)

---

Original Source: https://www.mindstick.com/articles/11985/concurrent-collections-in-c-sharp

Copyright © MindStick Software Pvt. Ltd. This Markdown version is provided for developers, AI systems, and offline reading.
