Quello che segue è un miglioramento sull'attuazione trovato da Jonathan. Innanzitutto esegue ogni gestore di eventi sul dispatcher ad esso associato, piuttosto che supponendo che siano tutti sullo stesso dispatcher (UI). In secondo luogo utilizza BeginInvoke per consentire all'elaborazione di continuare mentre attendiamo che il dispatcher sia disponibile. Ciò rende la soluzione molto più veloce nelle situazioni in cui il thread in background sta eseguendo molti aggiornamenti con l'elaborazione tra ciascuno di essi. Forse, ancora più importante, risolve i problemi causati dal blocco durante l'attesa di Invoke (i deadlock possono verificarsi ad esempio quando si utilizza WCF con ConcurrencyMode.Single).
public class MTObservableCollection<T> : ObservableCollection<T>
{
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler CollectionChanged = this.CollectionChanged;
if (CollectionChanged != null)
foreach (NotifyCollectionChangedEventHandler nh in CollectionChanged.GetInvocationList())
{
DispatcherObject dispObj = nh.Target as DispatcherObject;
if (dispObj != null)
{
Dispatcher dispatcher = dispObj.Dispatcher;
if (dispatcher != null && !dispatcher.CheckAccess())
{
dispatcher.BeginInvoke(
(Action)(() => nh.Invoke(this,
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))),
DispatcherPriority.DataBind);
continue;
}
}
nh.Invoke(this, e);
}
}
}
Poiché stiamo usando BeginInvoke, è possibile che il cambiamento dalla notifica viene annullata prima che il gestore è chiamato. Ciò in genere si traduce in un "Indice non compreso nell'intervallo."l'eccezione viene generata quando gli argomenti dell'evento vengono verificati rispetto al nuovo stato (alterato) della lista.Per evitare ciò, tutti gli eventi in ritardo vengono sostituiti con Ripristina eventi.Questo potrebbe causare un eccessivo ridisegno in alcuni casi.
fonte
2012-09-04 00:32:27
provare il collegamento seguente che fornisce una soluzione thread-safe che funziona da qualsiasi thread e può essere legato a via più thread UI: http: //www.codeproject .com/Articles/64936/Multithreaded-ObservableImmutableCollection – Anthony