Matt Burland
Matt Burland

Reputation: 45155

Adding items to observable collection causing exception with collection view

So I have an ObservableCollection<Foo> and I add an item to it like this:

Items.AddFromThread(svm);

Where AddFromThread is an extension method that looks like this:

public static void AddFromThread<T>(this ICollection<T> s, T obj)
{
    if (System.Windows.Application.Current.Dispatcher.Thread != System.Threading.Thread.CurrentThread)
    {
        System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() => s.AddFromThread(obj)), null);
    }
    else
    {
        s.Add(obj);
    }
}

This was working fine, but just recently I've started getting errors with the Add method:

An unhandled exception of type 'System.NotSupportedException' occurred in PresentationFramework.dll

Additional information: This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

Now I'm adding my item to my ObservableCollection from the dispatcher thread - that's what the check is for, so this seems like it should be impossible. But it's complaining not about my observable collection, but about the CollectionView. My UI is actually binding an ICollectionView that is created from Items like this:

filteredItems = CollectionViewSource.GetDefaultView(Items);

So what is happening here? If I'm adding from the UI thread, shouldn't the CollectionView be getting updated from the same thread? If not, how do I make it so that it does.

The worse part is that this was working fine for a long time and I didn't change anything that might have impacted this as far as I know.

Upvotes: 4

Views: 1455

Answers (1)

Matt Burland
Matt Burland

Reputation: 45155

Ok - so a little investigation and it appears that the CollectionView was being created on a different thread itself and that seems to be the root of the problem. Although why it didn't seem to be a problem before is still puzzling.

So I fixed it to make sure that the code that creates the CollectionView is also running on the Dispatcher.Thread. The error message was misleading in this case. The problem wasn't that I was trying to add from a non-UI thread, the problem was that I was adding from a UI thread, but to something that lived on a different thread.

Upvotes: 4

Related Questions