Saltar al contenido

Este tipo de CollectionView no admite cambios en su SourceCollection desde un subproceso diferente del subproceso Dispatcher

No busques más en otros sitios ya que estás al sitio adecuado, contamos con la solución que buscas pero sin problema.

Solución:

Dado que su ObservableCollection se crea en el subproceso de la interfaz de usuario, solo puede modificarlo desde el subproceso de la interfaz de usuario y no desde otros subprocesos. Esto se denomina afinidad de subprocesos.

Si alguna vez necesita actualizar los objetos creados en el subproceso de la interfaz de usuario desde un subproceso diferente, simplemente put the delegate on UI Dispatcher y eso funcionará para que lo delegues en el subproceso de la interfaz de usuario. Esto funcionará –

    public void Load()
    
        matchList = new List();
        matchList = proxy.GetMatch().ToList();

        foreach (EfesBet.DataContract.GetMatchDetailsDC match in matchList)
        
            App.Current.Dispatcher.Invoke((Action)delegate // <--- HERE
            
                _matchObsCollection.Add(match);
            );
        
    

Si no me equivoco, en WPF 4.5, debería poder hacer esto sin ningún problema.

Ahora, para resolver esto, debe usar el contexto de sincronización. Antes de iniciar el subproceso, debe almacenar el contexto de sincronización en el subproceso de interfaz de usuario.

var uiContext = SynchronizationContext.Current;

Luego lo usas en tu hilo:

uiContext.Send(x => _matchObsCollection.Add(match), null);

Eche un vistazo a este tutorial http://www.codeproject.com/Articles/31971/Understanding-SynchronizationContext-Part-I

Puedes hacerlo:

App.Current.Dispatcher.Invoke((System.Action)delegate
             
               _matchObsCollection.Add(match)
             );

Para .NET 4.5+: puede seguir la respuesta de Daniel. En su ejemplo, le da la responsabilidad al editor de que debe llamar o invocar en el hilo correcto:

var uiContext = SynchronizationContext.Current;
uiContext.Send(x => _matchObsCollection.Add(match), null);

O puede poner la responsabilidad en su servicio/modelo de vista/lo que sea y simplemente habilitar CollectionSynchronization. De esta manera, si realiza una llamada, no tiene que preocuparse sobre en qué hilo se encuentra y en cuál realiza la llamada. La responsabilidad ya no es del Editor.
(Esto puede generar una pequeña sobrecarga de rendimiento, pero hacerlo en un servicio central puede ahorrarle muchas excepciones y facilitar el mantenimiento de la aplicación).

private static object _lock = new object();

public MainWindowViewModel()

    // ...
    _matchObsCollection = new ObservableCollection();
    BindingOperations.EnableCollectionSynchronization(_matchObsCollection , _lock);
 

Más información: https://msdn.microsoft.com/en-us/library/system.windows.data.bindingoperations.enablecollectionsynchronization(v=vs.110).aspx

En Visual Studio 2015 (Pro), vaya a Depurar --> Windows --> Subprocesos para depurar fácilmente y ver en qué subprocesos se encuentra.

Si te animas, puedes dejar una división acerca de qué te ha parecido este tutorial.

¡Haz clic para puntuar esta entrada!
(Votos: 4 Promedio: 4.5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *