BindingOperations.EnableCollectionSynchronization Method (IEnumerable, Object, CollectionSynchronizationCallback)

.NET Framework (current version)

The .NET API Reference documentation has a new home. Visit the .NET API Browser on to see the new experience.

Enables a CollectionView object to participate in synchronized access to a collection used on multiple threads by using a mechanism other than a simple lock.

Namespace:   System.Windows.Data
Assembly:  PresentationFramework (in PresentationFramework.dll)

public static void EnableCollectionSynchronization(
	IEnumerable collection,
	object context,
	CollectionSynchronizationCallback synchronizationCallback


Type: System.Collections.IEnumerable

The collection that needs synchronized access.

Type: System.Object

An object that is passed to the callback.

Type: System.Windows.Data.CollectionSynchronizationCallback

The callback that is invoked whenever access to the collection is required.

A WPF application can display a collection of data using an ItemsControl or one of its subclasses (ListBox, DataGrid, TreeView, ListView, etc.). WPF channels all its access to the collection through a subclass of CollectionView. Both the ItemsControl and the CollectionView have affinity to the thread on which the ItemsControl was created, meaning that using them on a different thread is forbidden and throws an exception. In effect, this restriction applies to the collection as well.

You may want to use the collection on multiple threads. For example, you want to update the collection (add or remove items) on a "data-gathering" thread, while displaying the results on a "user interface" thread, so that the UI remains responsive while data-gathering is happening. In such a situation, you are responsible for ensuring synchronized ("thread-safe") access to the collection and for guaranteeing that access from WPF (specifically from CollectionView) participates in the same synchronization mechanism. By calling the EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback) method, you can do this by using a synchronization mechanism such as a semaphore, a reset event, etc.

To use a collection on multiple threads, one of which is the UI thread that owns the ItemsControl, you must do the following:

  1. Choose a synchronization mechanism.

  2. Synchronize all access from the application to the collection using that mechanism.

  3. Call EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback) to inform WPF that you are using a mechanism other than simple locking.

    • The call must occur on the UI thread.

    • The call must occur before using the collection on a different thread or before attaching the collection to the ItemsControl, whichever is later.

  4. Ensure that a change to the collection and the notification of that change (through CollectionChanged are atomic; no access from other threads can intervene.  (This is usually free. For instance, ObservableCollection<T> guarantees this, provided that all changes are protected by synchronization.)

  5. If you call DisableCollectionSynchronization, that call must also occur on the UI thread.

  6. If you want to use the same collection on multiple UI threads, you must call EnableCollectionSynchronization (and DisableCollectionSynchronization, if needed) separately on each UI thread.

  7. Avoid deadlock.  This is already the application's responsibility once it chooses to use synchronization, but it must also take into account WPF's participation in the synchronization. (See more, below.)

In return, WPF provides the following behavior:

  • The CollectionView accesses the collection by calling the registered CollectionSynchronizationCallback with the following arguments:

    • collection: the collection of interest.

    • context: the registered context object.

    • accessMethod: a delegate that performs the actual access.

    • writeAccess: true if the delegate will modify the collection; false otherwise.

    Your CollectionSynchronizationCallback should establish synchronization on the collection (using the context object and the writeAccess value, as appropriate), and call the accessMethod, then release synchronization.

  • The CollectionView maintains a "shadow copy" of the collection for use on the UI thread.

  • CollectionChanged events are queued up as they arrive (on any thread).

  • Pending events are applied to the shadow copy asynchronously on the UI thread when it has the opportunity to do so.

  • The CollectionView will not directly use any other synchronization mechanism visible to the application. This is WPF's way of helping to avoid deadlock (see the previous item 7).

The net effect is that you can change the collection on any thread, and those changes eventually appear in the ItemsControl when the UI thread has time to "catch up".  The implementation has been tuned to throttle the rate that changes flow into the UI thread to keep background threads from saturating the UI thread and starving the response to normal user input.

The context parameter is an arbitrary object that is passed to the callback. You can use it to determine the synchronization mechanism used to control access to collection. context can be null.

.NET Framework
Available since 4.5
Return to top