¿Cómo hacer que ObservableCollection sea seguro para subprocesos?

System.InvalidOperationException: Collection was modified; enumeration operation may not execute. 

Estoy agregando / eliminando de un ObservableCollection que no está en un subproceso de interfaz de usuario.

Tengo un método que nombra EnqueueReport para agregar a la colección y un DequeueReport para eliminar de la recostackción.

El flujo de pasos es el siguiente:

  1. 1.call EnqueueReport siempre que se solicite un nuevo informe
  2. llamar a un método cada pocos segundos para comprobar si se genera el informe (esto tiene un bucle foreach que verifica el estado generado de todos los informes en ObservableCollection)
  3. llamar a DequeueReport si el informe se genera

No estoy mucho en las bibliotecas de C #. ¿Puede alguien por favor guiarme en esto?

Puede crear una versión sencilla y amistosa de la colección observable. Como el siguiente:

  public class MTObservableCollection : ObservableCollection { 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); } } } 

con eso ahora haz un hallazgo masivo y reemplaza y cambia todo tu ObservableCollection por MTObservableCollection y listo.

La solución que Franck publicó aquí funcionará en el caso de que un hilo esté agregando cosas, pero ObservableCollection (y List, en el que se basa) no son seguros para subprocesos. Si hay varios hilos que escriben en la colección, podrían introducirse errores difíciles de rastrear. Escribí una versión de ObservableCollection que usa un ReaderWriteLockSlim para ser realmente seguro para subprocesos.

Lamentablemente, tocó el límite de caracteres de StackOverflow, por lo que aquí está en PasteBin. Esto debería funcionar al 100% con múltiples lectores / escritores. Al igual que regularmente con ObservableCollection, no es válido modificar la colección en una callback (en el hilo que recibió la callback).

A partir de .net framwork 4.5, puede usar la sincronización de colecciones nativas.

BindingOperations.EnableCollectionSynchronization(YourCollection, YourLockObject);

YourLockObject es una instancia de cualquier objeto, por ejemplo, new Object(); . Usa uno por colección

Esto elimina la necesidad de una clase especial o algo. Solo habilita y disfruta;)

PD: BindingOperations reside en Namespace System.Windows.Data .

Puede usar una clase ObservableConcurrentCollection. Se encuentran en un paquete provisto por Microsoft en la biblioteca de Extras de Extensiones Paralelas.

Puede obtenerlo previamente creado por la comunidad en Nuget: https://www.nuget.org/packages/ParallelExtensionsExtras/

O consíguelo de Microsoft aquí:

https://code.msdn.microsoft.com/ParExtSamples