This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread
Since your ObservableCollection is created on UI thread, you can only modify it from UI thread and not from other threads. This is termed as thread affinity.
If you ever need to update objects created on UI thread from different thread, simply put the delegate on UI Dispatcher
and that will do work for you delegating it to UI thread. This will work -
public void Load()
{
matchList = new List<GetMatchDetailsDC>();
matchList = proxy.GetMatch().ToList();
foreach (EfesBet.DataContract.GetMatchDetailsDC match in matchList)
{
App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
{
_matchObsCollection.Add(match);
});
}
}
If I'm not mistaken, in WPF 4.5, you should be able to do this without any problem.
Now to solve this, you should use the synchronization context. Before you launch the thread, you have to store the synchronization context in the ui thread.
var uiContext = SynchronizationContext.Current;
Then you use it in your thread:
uiContext.Send(x => _matchObsCollection.Add(match), null);
Take a look at this tuto http://www.codeproject.com/Articles/31971/Understanding-SynchronizationContext-Part-I
You can do this:
App.Current.Dispatcher.Invoke((System.Action)delegate
{
_matchObsCollection.Add(match)
});
For .NET 4.5+: You can follow the answer of Daniel. In his example you give the responsability to the publisher that they need to call or invoke on the correct thread:
var uiContext = SynchronizationContext.Current;
uiContext.Send(x => _matchObsCollection.Add(match), null);
Or you could put the responsability to your service/viewmodel/whatever and simply enable CollectionSynchronization. This way if you make a call you don't have to worry on which thread you are on and on which one you make the call. The responsability is not for the Publisher anymore. (This may give you a little performance overhead but doing this in a central service, it can save you a lot of exceptions and gives you easier application maintenance.)
private static object _lock = new object();
public MainWindowViewModel()
{
// ...
_matchObsCollection = new ObservableCollection<EfesBet.DataContract.GetMatchDetailsDC>();
BindingOperations.EnableCollectionSynchronization(_matchObsCollection , _lock);
}
More info: https://msdn.microsoft.com/en-us/library/system.windows.data.bindingoperations.enablecollectionsynchronization(v=vs.110).aspx
In Visual Studio 2015 (Pro) go to Debug --> Windows --> Threads to easily debug and see on which threads you are on.