ObservableCollection Dispatching

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

Description

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

Example

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; }
        set
        {
            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);
    models.Add(model);
    model.Name = "Some other name";
});

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

Comments

No comments yet.