La mejor manera de resolver esto es pasar el objeto Dispatcher
al método de inicio del subproceso en segundo plano.
void DoBackgroundOperation(ObservableCollection<SomeType> col) {
var dispatcher = Dispatcher.CurrentDispatcher;
ThreadStart start =() => BackgroundStart(dispatcher, col);
var t = new Thread(start);
t.Start();
}
private static void BackgroundStart(
Dispatcher dispatcher,
ObservableCollection<SomeType> col) {
...
SomeType t = GetSomeTypeObject();
Action del =() => col.Add(t);
dispatcher.Invoke(del);
}
Ahora más adelante, cuando es necesario agregar a la colección se puede utilizar el objeto de interfaz de usuario Dispatcher
.
Como señaló @Reed, se logra una solución más general al usar SynchronizationContext
. Aquí hay una muestra de estilo funcional que usa SynchronizationContext
para crear un delegado responsable de agregar nuevos valores. Esto tiene la ventaja de ocultar tanto la colección como el modelo de subprocesamiento desde el código que crea el objeto.
void DoBackgroundOperation(ObservableCollection<SomeType> col) {
var context = SynchronizationContext.Current;
Action<SomeType> addFunc = (SomeType st) => context.Send(() => col.Add(st), null);
ThreadStart start =() => BackgroundStart(addFunc);
var t = new Thread(start);
t.Start();
}
private static void BackgroundStart(Action<SomeType> addFunc) {
...
SomeType t = GetSomeTypeObject();
addFunc(t);
}
Personalmente, no pude hacer que funcione con los enlaces proporcionados. Necesitaba utilizar el enfoque de JaredPas que mencionaste. –
Pruebe el siguiente enlace que proporciona una solución de seguridad de subprocesos que funciona desde cualquier subproceso y se puede vincular a través de varios subprocesos de UI: http://www.codeproject.com/Articles/64936/Multithreaded-ObservableImmutableCollection – Anthony
El artículo que hace referencia por AnthonyPaulO requiere el paquete Inmutable Collections NuGet y solo funciona con .NET4.5. ¿Hay algo similar para .NET4.0? – Dave