I am using the BackgroundWorker
to update an ObservableCollection
but it gives this error:
\"This type of
CollectionVi
If you initialize the collection in the constructor it will be on the default Application thread.
To invoke the main thread you can do this:
Application.Current.Dispatcher.Invoke((Action)(() =>
{
//Do something here.
}));
You have to cast the Anonymous delegate as an action otherwise it gets confused ¯\O_o/¯
If you are using the Async CTP then you can do this
Application.Current.Dispatcher.InvokeAsync(()=>
{
//Do something here.
});
You are using BGW, it was designed to solve your problem. But you'll have to use it properly, update the collection in a ProgressChanged or RunWorkerCompleted event handler. If that's what you are doing then you created the BGW instance on the wrong thread. It has to be done on the UI thread.
I had the same problem while reloading an observableCollection from an event (on DataReceived) raised by the serial port class. I used MVVM; I tried to update the collection with the BackgroundWorker, but it raised the "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.". I tried many others solutions found online, but the only one that solved my problem (immediately!) was to use a multi-threading observable collection (I used the one in this post: Where do I get a thread-safe CollectionView?)
If MVVM
public class MainWindowViewModel : ViewModel {
private ICommand loadcommand;
public ICommand LoadCommand { get { return loadcommand ?? (loadcommand = new RelayCommand(param => Load())); } }
private ObservableCollection<ViewModel> items;
public ObservableCollection<ViewModel> Items {
get {
if (items == null) {
items = new ObservableCollection<ViewModel>();
}
return items;
}
}
public void Load() {
BackgroundWorker bgworker = new BackgroundWorker();
bgworker.WorkerReportsProgress = true;
bgworker.DoWork += (s, e) => {
for(int i=0; i<10; i++) {
System.Threading.Thread.Sleep(1000);
bgworker.ReportProgress(i, new List<ViewModel>());
}
e.Result = null;
};
bgworker.ProgressChanged += (s, e) => {
List<ViewModel> partialresult = (List<ViewModel>)e.UserState;
partialresult.ForEach(i => {
Items.Add(i);
});
};
bgworker.RunWorkerCompleted += (s, e) => {
//do anything here
};
bgworker.RunWorkerAsync();
}
}
Try This:
this.Dispatcher.Invoke(DispatcherPriority.Background, new Action(
() =>
{
//Code
}));