ConcurrentObservableCollection<T> Class

Thread-safe collection. You can safely bind it to a UI control using the property ConcurrentObservableCollection<T>.AsObservable.

public class ConcurrentObservableCollection<T> : ICollection<T>, IEnumerable<T>, IList<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection, IEnumerable, IList

Type parameters

T
The type of elements in the collection.

Remarks

The collection itself can be modified from any thread. The collection exposed by ConcurrentObservableCollection<T>.AsObservable raises its change notifications on the thread associated with the SynchronizationContext provided to the constructor.

All the notifications of an operation are queued before any of them is raised, and the notifications are never raised recursively: a handler that modifies the collection gets the notifications of its own modification after the ones already queued, so ConcurrentObservableCollection<T>.AsObservable ends up in the same state as this collection. A handler that throws doesn't prevent the remaining notifications from being raised: the other notifications of the same modification (Count, Item[] and CollectionChanged) and the notifications of the following modifications are still raised. The handlers subscribed to the same event after the one that threw are not invoked, as with any event. The exception is rethrown to the caller of the modification once the queued notifications have all been raised, as an AggregateException when several handlers threw.

The indexed modifications made through ConcurrentObservableCollection<T>.AsObservable (the indexer, Insert and RemoveAt) use the indices of the view, which can be behind this collection while notifications are pending. They are applied to the item the view shows at that index, wherever it is in this collection. When that item was removed, or the collection was cleared or sorted, by a modification whose notification is still pending, an InvalidOperationException is thrown and nothing is modified.

The notifications are raised once the modification has released the internal lock, so a handler can wait for another thread that modifies the collection without deadlocking.

When the synchronization context refuses the callback, for instance because the thread it is bound to is gone, the exception is propagated to the caller that modified the collection. The modification is kept, and its notification stays queued until a later modification succeeds in posting to the context.

Example

var collection = new ConcurrentObservableCollection<string>();
myListBox.ItemsSource = collection.AsObservable;

// Safe to call from any thread
await Task.Run(() => collection.Add("Item 1"));
Implements

Constructors

NameDescription
ConcurrentObservableCollection()Initializes a new instance of the ConcurrentObservableCollection<T> class using the synchronization context of the current thread.
ConcurrentObservableCollection(SynchronizationContext)Initializes a new instance of the ConcurrentObservableCollection<T> class with the specified synchronization context.

ConcurrentObservableCollection overloads

ConcurrentObservableCollection()

ConcurrentObservableCollection.cs

Initializes a new instance of the ConcurrentObservableCollection<T> class using the synchronization context of the current thread.

public ConcurrentObservableCollection()
Remarks

When the current thread has no synchronization context, a default SynchronizationContext is used and the collection returned by ConcurrentObservableCollection<T>.AsObservable raises its change notifications on the thread pool. The handlers can access the collection returned by ConcurrentObservableCollection<T>.AsObservable while they run, but no other thread can. Use the ConcurrentObservableCollection<T> constructor to bind the collection to a specific thread.

ConcurrentObservableCollection(SynchronizationContext)

ConcurrentObservableCollection.cs

Initializes a new instance of the ConcurrentObservableCollection<T> class with the specified synchronization context.

public ConcurrentObservableCollection(SynchronizationContext synchronizationContext)
Parameters
synchronizationContext SynchronizationContext
The synchronization context used to raise collection change notifications.

Properties

NameDescription
AsObservableGets an observable collection that can be bound to UI controls.
CountGets the number of elements in the collection.
SupportRangeNotificationsWhen set to true AddRange and InsertRange methods raise NotifyCollectionChanged with all items instead of one event per item.
System.Collections.Generic.ICollection<T>.IsReadOnly
System.Collections.ICollection.Count
System.Collections.ICollection.IsSynchronized
System.Collections.ICollection.SyncRoot
System.Collections.IList.IsFixedSize
System.Collections.IList.IsReadOnly

Gets an observable collection that can be bound to UI controls.

public IReadOnlyObservableCollection<T> AsObservable { get; }

Gets the number of elements in the collection.

public int Count { get; }

Property value

int

SupportRangeNotifications

ConcurrentObservableCollection.cs

When set to true AddRange and InsertRange methods raise NotifyCollectionChanged with all items instead of one event per item.

public bool SupportRangeNotifications { get; set; }

Property value

bool

Remarks

Most UI controls, such as the WPF ones, don't support batch modifications

System.Collections.Generic.ICollection<T>.IsReadOnly

ConcurrentObservableCollection.cs
bool ICollection<T>.IsReadOnly { get; }

Property value

bool

No documentation is available.

System.Collections.ICollection.Count

ConcurrentObservableCollection.cs
int ICollection.Count { get; }

Property value

int

No documentation is available.

System.Collections.ICollection.IsSynchronized

ConcurrentObservableCollection.cs
bool ICollection.IsSynchronized { get; }

Property value

bool

No documentation is available.

System.Collections.ICollection.SyncRoot

ConcurrentObservableCollection.cs
object ICollection.SyncRoot { get; }

Property value

object

No documentation is available.

System.Collections.IList.IsFixedSize

ConcurrentObservableCollection.cs
bool IList.IsFixedSize { get; }

Property value

bool

No documentation is available.

System.Collections.IList.IsReadOnly

ConcurrentObservableCollection.cs
bool IList.IsReadOnly { get; }

Property value

bool

No documentation is available.

Indexers

NameDescription
this[int]Gets or sets the element at the specified index.
this[int]

Gets or sets the element at the specified index.

public T this[int index] { get; set; }

Parameters

index int

Property value

T

object? IList.this[int index] { get; set; }

Parameters

index int

Property value

object?

No documentation is available.

Methods

NameDescription
Add(T)Adds an item to the collection.
AddRange(IEnumerable<T>)Adds multiple items to the collection.
AddRange(T[])Adds multiple items to the collection.
Clear()Removes all items from the collection.
Contains(T)Determines whether the collection contains a specific item.
CopyTo(T[], int)Copies the elements of the collection to an array, starting at a particular array index.
GetEnumerator()Returns an enumerator that iterates through the collection.
IndexOf(T)Determines the index of a specific item in the collection.
Insert(int, T)Inserts an item into the collection at the specified index.
InsertRange(int, IEnumerable<T>)Inserts multiple items into the collection at the specified index.
IsOnSynchronizationContextThread()Determines whether the current thread is the thread the collection returned by ConcurrentObservableCollection<T>.AsObservable is bound to. When it is, change notifications are raised synchronously instead of being posted to SynchronizationContext.
Remove(T)Removes the first occurrence of a specific item from the collection.
RemoveAt(int)Removes the item at the specified index.
Sort()Sorts the elements in the collection using the default comparer.
Sort(IComparer<T>?)Sorts the elements in the collection using the specified comparer.
StableSort()Performs a stable sort on the collection using the default comparer.
StableSort(IComparer<T>?)Performs a stable sort on the collection using the specified comparer.
System.Collections.ICollection.CopyTo(Array, int)
System.Collections.IEnumerable.GetEnumerator()
System.Collections.IList.Add(object?)
System.Collections.IList.Clear()
System.Collections.IList.Contains(object?)
System.Collections.IList.IndexOf(object?)
System.Collections.IList.Insert(int, object?)
System.Collections.IList.Remove(object?)
System.Collections.IList.RemoveAt(int)

Adds an item to the collection.

public void Add(T item)

Parameters

item T
The item to add.

AddRange overloads

AddRange(IEnumerable<T>)

ConcurrentObservableCollection.cs

Adds multiple items to the collection.

public void AddRange(IEnumerable<T> items)
Parameters
items IEnumerable<T>
The items to add.
Remarks

items is enumerated before the collection is modified, so the enumeration can modify the collection.

Adds multiple items to the collection.

public void AddRange(params T[] items)
Parameters
items T[]
The items to add.

Removes all items from the collection.

public void Clear()

Determines whether the collection contains a specific item.

public bool Contains(T item)

Parameters

item T
The item to locate.

Returns

bool true if the item is found; otherwise, false.

Copies the elements of the collection to an array, starting at a particular array index.

public void CopyTo(T[] array, int arrayIndex)

Parameters

array T[]
The destination array.
arrayIndex int
The zero-based index in the array at which copying begins.

Returns an enumerator that iterates through the collection.

public IEnumerator<T> GetEnumerator()

Determines the index of a specific item in the collection.

public int IndexOf(T item)

Parameters

item T
The item to locate.

Returns

int The index of the item if found; otherwise, -1.

Inserts an item into the collection at the specified index.

public void Insert(int index, T item)

Parameters

index int
The zero-based index at which the item should be inserted.
item T
The item to insert.

InsertRange(int, IEnumerable<T>)

ConcurrentObservableCollection.cs

Inserts multiple items into the collection at the specified index.

public void InsertRange(int index, IEnumerable<T> items)

Parameters

index int
The zero-based index at which items should be inserted.
items IEnumerable<T>
The items to insert.

Remarks

items is enumerated before the collection is modified, so the enumeration can modify the collection. index is validated against the collection once the enumeration is complete.

IsOnSynchronizationContextThread()

ConcurrentObservableCollection.cs

Determines whether the current thread is the thread the collection returned by ConcurrentObservableCollection<T>.AsObservable is bound to. When it is, change notifications are raised synchronously instead of being posted to SynchronizationContext.

protected internal virtual bool IsOnSynchronizationContextThread()

Returns

bool true when the current thread can raise the notifications directly; otherwise, false.

Remarks

The current thread is considered to be the right one when it runs the SynchronizationContext provided to the constructor. The WPF and Windows Forms synchronization contexts are also matched by thread, as they run their callbacks on a single thread but expose several instances for it. Override this method to support another thread-affine context.

Removes the first occurrence of a specific item from the collection.

public bool Remove(T item)

Parameters

item T
The item to remove.

Returns

bool true if the item was removed; otherwise, false.

Removes the item at the specified index.

public void RemoveAt(int index)

Parameters

index int
The zero-based index of the item to remove.

Sort overloads

Sorts the elements in the collection using the default comparer.

public void Sort()

Sorts the elements in the collection using the specified comparer.

public void Sort(IComparer<T>? comparer)
Parameters
comparer IComparer<T>?
The comparer to use when comparing elements.
Exceptions
InvalidOperationException
comparer modified the collection. The collection is not sorted.

StableSort overloads

Performs a stable sort on the collection using the default comparer.

public void StableSort()

StableSort(IComparer<T>?)

ConcurrentObservableCollection.cs

Performs a stable sort on the collection using the specified comparer.

public void StableSort(IComparer<T>? comparer)
Parameters
comparer IComparer<T>?
The comparer to use when comparing elements.
Exceptions
InvalidOperationException
comparer modified the collection. The collection is not sorted.

System.Collections.ICollection.CopyTo(Array, int)

ConcurrentObservableCollection.cs
void ICollection.CopyTo(Array array, int index)

Parameters

array Array
index int

No documentation is available.

System.Collections.IEnumerable.GetEnumerator()

ConcurrentObservableCollection.cs
IEnumerator IEnumerable.GetEnumerator()

No documentation is available.

System.Collections.IList.Add(object?)

ConcurrentObservableCollection.cs
int IList.Add(object? value)

Parameters

value object?

Returns

int

No documentation is available.

System.Collections.IList.Clear()

ConcurrentObservableCollection.cs
void IList.Clear()

No documentation is available.

System.Collections.IList.Contains(object?)

ConcurrentObservableCollection.cs
bool IList.Contains(object? value)

Parameters

value object?

Returns

bool

No documentation is available.

System.Collections.IList.IndexOf(object?)

ConcurrentObservableCollection.cs
int IList.IndexOf(object? value)

Parameters

value object?

Returns

int

No documentation is available.

System.Collections.IList.Insert(int, object?)

ConcurrentObservableCollection.cs
void IList.Insert(int index, object? value)

Parameters

index int
value object?

No documentation is available.

System.Collections.IList.Remove(object?)

ConcurrentObservableCollection.cs
void IList.Remove(object? value)

Parameters

value object?

No documentation is available.

System.Collections.IList.RemoveAt(int)

ConcurrentObservableCollection.cs
void IList.RemoveAt(int index)

Parameters

index int

No documentation is available.