W WPF klasa CollectionView jest niezwykle przydatna jeśli chcemy w prosty sposób zaimplementować mechanizm sortowania, grupowania lub filtrowania. Używając jej jednak w programowaniu asynchronicznym podczas uaktualniania tej kolekcji z innego wątku, dostaniemy następujący komunikat:
The calling thread cannot access this object because a different thread owns it
Nie dziwota, jest to normalnie zachowanie, które często się zdarza, ponieważ CollectionView nie obsługuje zmian własnej kolekcji z wątku innego niż Dispatcher. Co jednak zrobić aby obejść ten problem? Po pierwsze musimy mieć obiekt dispatcher'a, która w WPF'ie jest klasą zapewniającą usługi do zarządzania wątkami, np. synchronizacji. Jeśli korzystamy ze wzorca MVVM (Model-View-ViewModel), pierwsze co musimy zrobić to przekazać obiekt dispatcher'a do ViewModelu, np w konstruktorze:
private Dispatcher currentDispatcher; public ViewModel(Dispatcher currentDispatcher) { this.currentDispatcher = currentDispatcher; }
Następnie aby dodawać obiekty do kolekcji CollectionViewSource, należy wykonać następujący kod:
currentDispatcher.Invoke(new Action(()=> { this.collectionViewSource.Add(someObject); }));
Można od razu tak:
OdpowiedzUsuńApplication.Current.Dispatcher.BeginInvoke(new Action(() =>
{
this.collectionViewSource.Add(someObject);
}));