Ok, I recently implemented a background worker to perform saving and loading of data.
However, getting this to work on a save command has proved difficult.
Basically, my save command generates an event, that notifies a collection view model, that an Item has been added and that the item should be added to its own ObservableCollection.
At this point, I get the usual exception saying I can NOT update an ICollection on a different thread. I have tried creating a new list type that calls Dispatcher.Invoke
, however this still generates the same exception.
I was wondering whether anyone else has any suggestions on how best to tackle this?
So currently I have a class that Inherits from ObservableCollection:
public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
{
public ThreadSafeObservableCollection(List<T> collection)
: base(collection)
{
dispatcher = Dispatcher.CurrentDispatcher;
rwLock = new ReaderWriterLock();
}
protected override void InsertItem(int index, T item)
{
if (dispatcher.CheckAccess())
{
if (index > this.Count)
return;
LockCookie c = rwLock.UpgradeToWriterLock(-1);
base.InsertItem(index, item);
rwLock.DowngradeFromWriterLock(ref c);
}
else
{
object[] obj = new object[] { index, item };
dispatcher.Invoke(
DispatcherPriority.Send,
(SendOrPostCallback)delegate { InsertItemImpl(obj); },
obj);
}
}
I then have a view model class that has a background worker which carries out the save.
Once the save is complete, an event is fired to another view model to update its list.
protected override void OnObjectAddedToRepository(object sender, ObjectEventArgs<cdAdministrators> e)
{
Dispatcher x = Dispatcher.CurrentDispatcher;
var viewModel = new AdministratorViewModel(e.EventObject, DataAccess);
viewModel.RecentlyAdded = true;
viewModel.ItemSelected += this.OnItemSelected;
this.AllViewModels.Add(viewModel);
RecentlyAddedViewModel = viewModel;
OnPropertyChanged(null);
}
Both lists are created by a separate background worker thread.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…