Parece que el ObservableCollection solo admite agregar, quitar, borrar la operación del subproceso de UI, Lanza excepción de no admitir si se opera mediante un subproceso NO UI. Intenté anular los métodos de ObservableCollection, desafortunadamente, encontré muchos problemas. ¿Cualquiera puede proporcionarme una muestra de ObservableCollection que pueda ser operada por varios hilos? ¡Muchas gracias!No se puede operar ObservableCollection en varios subprocesos
Respuesta
Usando el enlace proporcionado por Kent, podría utilizar el siguiente código para modificar una colección a través de hilos:
while (!Monitor.TryEnter(_lock, 10))
{
DoEvents();
}
try
{
//modify collection
}
finally
{
Monitor.Exit(_lock);
}
Sin embargo, si lo que buscas para modificar la colección en su hilo original puede probar a usar una devolución de llamada a su subproceso de interfaz de usuario. Que normalmente hago algo como esto:
this.Dispatcher.Invoke(new MyDelegate((myParam) =>
{
this.MyCollection.Add(myParam);
}), state);
Por los sonidos del original publicar, (s) que quiere una implementación de ObservableCollection que se puede utilizar desde cualquier tema sin tener en cuenta el enlace de la interfaz de usuario.Puede ser muy útil en su capa de negocios, por ejemplo. Por supuesto, podría haber entendido mal el propósito de la pregunta ... –
Además, Mark, no necesariamente sé si el uso de BeginInvoke es la mejor idea, porque no se garantiza absolutamente el orden de los artículos. Invoke() es el camino a seguir. –
Actualicé mi respuesta para reflejar ambas posibles respuestas. Gracias Kent. –
Has básicamente tiene que invocar o BeginInvoke hacia el hilo de interfaz de usuario para hacer esas operaciones.
Public Delegate Sub AddItemDelegate(ByVal item As T)
Public Sub AddItem(ByVal item As T)
If Application.Current.Dispatcher.CheckAccess() Then
Me.Add(item)
Else
Application.Current.Dispatcher.Invoke(Threading.DispatcherPriority.Normal, New AddItemDelegate(AddressOf AddItem), item)
End If
End Sub
Personalmente, encuentro que el estilo de respuesta de Bob es más fácil de usar que el estilo de respuesta de Mark. Estos son los fragmentos C# WPF para hacer esto:
en el constructor de la clase, obtener el despachador actual a medida que crea sus colecciones observables. Porque, como señaló, las modificaciones necesarias para se deben realizar en el thread original, que puede no ser el principal hilo GUI. So Application.Current.Dispatcher no es correcto, y no todas las clases tienen un this.Dispatcher.
_dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher; _data = new ObservableCollection<MyDataItemClass>();
Utilice el despachador para invocar sus secciones de código que necesita el hilo original.
_dispatcher.Invoke(new Action(() => { _data.Add(dataItem); }));
Que debe hacer el truco para usted. Aunque hay situaciones, puede preferir . BeginInvoke en lugar de . Invoque.
Es posible que desee investigar mi respuesta a esto tal vez, pero please note
que el código vino de aquí y no se puede acreditar a mí. Aunque traté de implementarlo en VB. : Original Site
Lo he usado para llenar un cuadro de lista WPF de una clase que tiene un ObservableCollectionEx poblado asincrónicamente desde una base de datos de acceso. Funciona.
public class ObservableCollectionEx<T> : ObservableCollection<T>
{
// Override the event so this class can access it
public override event System.Collections.Specialized.NotifyCollectionChangedEventHandler
CollectionChanged;
protected override void OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// Be nice - use BlockReentrancy like MSDN said
using (BlockReentrancy())
{
System.Collections.Specialized.NotifyCollectionChangedEventHandler eventHandler = CollectionChanged;
if (eventHandler == null)
return;
Delegate[] delegates = eventHandler.GetInvocationList();
// Walk thru invocation list
foreach (System.Collections.Specialized.NotifyCollectionChangedEventHandler handler in delegates)
{
DispatcherObject dispatcherObject = handler.Target as DispatcherObject;
// If the subscriber is a DispatcherObject and different thread
if (dispatcherObject != null && dispatcherObject.CheckAccess() == false)
{
// Invoke handler in the target dispatcher's thread
dispatcherObject.Dispatcher.Invoke(DispatcherPriority.DataBind, handler, this, e);
}
else // Execute handler as is
handler(this, e);
}
}
}
}
- 1. Foreach no puede operar en un grupo de métodos
- 2. ObservableCollection no se actualiza View
- 3. ¿Se puede dividir md5 para que se ejecute en varios núcleos/subprocesos?
- 4. Comprensión de varios subprocesos
- 5. ListView no se actualizó correctamente con ObservableCollection
- 6. ¿Por qué las clases como BindingList o ObservableCollection no son seguras para subprocesos?
- 7. Ejecutar tareas en varios subprocesos en node.js
- 8. Decapado de varios subprocesos en Python
- 9. Java: sincronización de subprocesos en varios servidores
- 10. ¿Se puede acceder de forma segura a las matrices estáticas desde varios subprocesos?
- 11. ¿Cómo se ejecutan varios procesos/subprocesos/interfaces de Tornado?
- 12. C# lectura de varios subprocesos de colecciones no modificables
- 13. Usando un ObservableCollection <T> con Subprocesos de fondo
- 14. python: se agrega al mismo archivo desde varios subprocesos
- 15. ¿Cómo esperaría a que se detengan varios subprocesos?
- 16. ¿No se puede agregar un componente Swing a varios contenedores?
- 17. ¿Por qué Parallel.ForEach no está ejecutando varios subprocesos?
- 18. Escribir en FileOutputStream desde varios subprocesos en Java
- 19. ¿Realmente Node.js usa varios subprocesos debajo?
- 20. Transacción de Entity Framework con varios subprocesos
- 21. ¿Cómo se modifican las funciones en tiempo de ejecución y luego se propagan a varios subprocesos?
- 22. java descarga varios archivos usando subprocesos
- 23. ¿Es seguro leer de varios subprocesos?
- 24. Consola de llamada.WriteLine de varios subprocesos
- 25. ¿El objeto Mapper de Hadoop está compartido en varios subprocesos?
- 26. Lectura de un único archivo de varios subprocesos en python
- 27. ¿Por qué ObservableCollection no admite cambios masivos?
- 28. ¿Cuándo elegir varios procesos sobre subprocesos en Java?
- 29. Gestión de sesiones de Spring + Hibernate en varios subprocesos
- 30. Operar en varias columnas a la vez
Salida [este mensaje] (http://kentb.blogspot.com/2008/01/cross-thread-collection-binding-in-wpf_19.html) en mi blog. –
El siguiente enlace tiene una solución que le permite enlazar a la colección desde cualquier subproceso de interfaz de usuario y modificarlo desde cualquier subproceso: http://www.codeproject.com/Articles/64936/Multithreaded-ObservableImmutableCollection – Anthony