Ok, ich habe kürzlich einen Hintergrund-Worker zum Speichern und Laden von Daten implementiert.Aktualisieren einer ObservableCollection mit einem Hintergrund-Worker in MVVM
Dies ist jedoch immer auf einem Sparbefehl zu arbeiten hat sich als schwierig erwiesen.
Grundsätzlich mein Befehl speichern generiert ein Ereignis, das eine Sammlung Ansicht Modell benachrichtigt, dass ein Element hinzugefügt wurde, und dass das Element in seine eigenen ObservableCollection hinzugefügt werden soll.
An diesem Punkt habe ich die übliche Ausnahme sagen, dass ich nicht eine ICollection auf einem anderen Thread aktualisieren kann. Ich habe versucht, einen neuen Listentyp zu erstellen, der Dispatcher.Invoke
aufruft, jedoch generiert dies immer noch die gleiche Ausnahme.
Ich habe mich gefragt, ob jemand irgendwelche Vorschläge, wie dies am besten zu bewältigen?
Also zur Zeit habe ich eine Klasse, die von ObservableCollection Erbt:
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);
}
}
ich dann eine Ansicht Modellklasse haben, die einen Hintergrund Arbeiter hat, die das Speichern ausführt.
Sobald das Speichern abgeschlossen ist, wird ein Ereignis in einer anderen Ansicht Modell feuert seine Liste zu aktualisieren.
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);
}
Beide Listen werden von einem separaten Hintergrund-Worker-Thread erstellt.
Hallo Jon, Vielen Dank für Ihre Antwort, Ich habe bereits ein Sammelobjekt, das auf InsertItem von ObserveableCollection Erbt dies tut Dispatcher.CheckAccess wenn falsche Dispather.BeginInvoke nicht dann ist dies jedoch immer noch nicht funktioniert ?? – jpgooner
@jpgooner: Sind Sie sicher, dass der Code tatsächlich verwendet wird? Können Sie sich ein kurzes, aber vollständiges Beispiel vorstellen, das das Problem aufzeigt? –
Ich habe weiter oben hinzugefügt, lassen Sie mich wissen, wenn Sie mehr brauchen, habe ich noch neu bin – jpgooner