ObservableCollection Dispatching

Collection: DispatchObservatorCollection<T>
Extension method: ObservatorCollectionExtensions.Dispatch(source, dispatcherQueue)


This collection listens to an IObservableCollection<T> and rebuilds an identical collection on the dispatcher thread. The resulting collection is completely thread safe.


The following example shows how to create a list of Model that will be processed on a different thread, but observed on the UI thread.

using System.ComponentModel;
using ZumtenSoft.WpfUtils.Threading;

public class Model : INotifyPropertyChanged
    private readonly DispatcherQueue _dispatcher;

    public Model(string name, DispatcherQueue dispatcher)
        _dispatcher = dispatcher;
        Name = name;

    private string _name;
    public string Name
        get { return _name; }
            if (_name != value)
                _name = value;

                // By using the DispatcherQueue to fire the PropertyChanged event,
                // we can be assured all the PropertyChanged events will be UI-compatible.
                _dispatcher.Push(() =>
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Name"));

    public event PropertyChangedEventHandler PropertyChanged;

Once this is completed, build a new DispatcherQueue, call the Dispatch() extension method
and the newly created collection can be assigned to any UI object.

// Here, the CurrentDispatcher should be pointing to the UI thread
DispatcherQueue dispatcher = new DispatcherQueue(Dispatcher.CurrentDispatcher);
IObservableCollection<Model> models = new ObservableCollection<Model>();
DispatchObservatorCollection<Model> dispatchedModels = models.Dispatch(dispatcher);

// Assign the collection to any UI object
listView.DataSource = dispatchedModels;

ThreadPool.QueueUserWorkItem(_ =>
    // Both the model's PropertyChanged event and the collection's CollectionChanged
    // events will be fired on the UI thread.
    Model model = new Model("Some name", dispatcher);
    model.Name = "Some other name";

Last edited May 19, 2013 at 10:44 PM by Zumten, version 4


No comments yet.