Próbowałem pobrać bibliotekę Rx i opracować ją w WPF z MVVM. Zepsułem moją aplikację do komponentów takich jak repozytorium i ViewModel. Moje repozytorium jest w stanie dostarczyć kolekcję studentów jeden po drugim, ale w chwili, gdy próbuję dodać do View ObservableCollection, zgłasza błąd wątku. Poświęciłem trochę wskazówek, żeby to zadziałało.Aktualizowanie obserwowalnej kolekcji z innego wątku
Odpowiedz
Musisz ustawić kontekst synchronizacji poprawnie używając
ObserveOn(SynchronizationContext.Current)
zobaczyć ten wpis na blogu
dla przykładu.
Oto przykład, który działa dla mnie:
<Page.Resources>
<ViewModel:ReactiveListViewModel x:Key="model"/>
</Page.Resources>
<Grid DataContext="{StaticResource model}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Content="Start" Command="{Binding StartCommand}"/>
<ListBox ItemsSource="{Binding Items}" Grid.Row="1"/>
</Grid>
public class ReactiveListViewModel : ViewModelBase
{
public ReactiveListViewModel()
{
Items = new ObservableCollection<long>();
StartCommand = new RelayCommand(Start);
}
public ICommand StartCommand { get; private set; }
private void Start()
{
var observable = Observable.Interval(TimeSpan.FromSeconds(1));
//Exception: This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
//observable.Subscribe(num => Items.Add(num));
// Works fine
observable.ObserveOn(SynchronizationContext.Current).Subscribe(num => Items.Add(num));
// Works fine
//observable.ObserveOnDispatcher().Subscribe(num => Items.Add(num));
}
public ObservableCollection<long> Items { get; private set; }
}
ta metoda działa, jeśli kod znajduje się w kodzie Xamls, ale potrzebuję ViewModel do dodania obiektu. Moje źródło to usługa Async wywoływana z ViewModel. W tym czasie SynchronitaionContext.Current nie ma żadnej wartości w ViewModel –
Dodałem przykład, który działa dla mnie. Zauważ, że dodałem Rx-Main i Rx-WPF przez NuGet. – Phil
Mój kod jest mniej więcej taki sam, ale moje pobieranie kolekcji i przypisanie odbywa się w Konstruktorze. Używam też Unity do rozwiązania klasy. Dodałem dokładny kod tutaj http://stackoverflow.com/questions/9377290/synchronizationcontext-current-is-null-on-resolving-withunity-in-wpf –
Czy Twój kod działa na wątku tła? Ponieważ wpływa na interfejs użytkownika, powiązana obserwacja ObservableCollection może być aktualizowana tylko w wątku UI/Dispatcher.
Zobacz podobną sprawę pod numerem WPF ObservableCollection Thread Safety.
Wszelkie zmiany w interfejsie powinny być wykonane przez wątek Dispatcher
. Dobrą praktyką, jeśli masz ciągły wątek zmieniający model widoku, jest zmuszenie selektorów właściwości do używania wątku programu rozsyłającego. W takim przypadku upewnij się, że nie zmienisz elementu interfejsu użytkownika w innym wątku.
Spróbuj:
public string Property
{
set
{
Dispatcher.BeginInvoke(()=> _property = value) ;
OnPropertyChanged("Property");
}
get
{
return _property;
}
}
- 1. Aktualizowanie kolekcji Scala bez wątku
- 2. Filtrowanie obserwowalnej kolekcji
- 3. Tworzenie obserwowalnej listy/kolekcji
- 4. Metoda uruchamiania głównego wątku z innego wątku
- 5. Obiekt dostępu z innego wątku
- 6. JavaFX - powiązanie właściwości z właściwościami każdego elementu w obserwowalnej kolekcji
- 7. C#: Pokaż okno dialogowe na wątku UI z innego wątku
- 8. Czy istnieje sposób na przekształcenie obserwowalnej kolekcji w zwykłą kolekcję?
- 9. Wymowne - Aktualizowanie wszystkich modeli w kolekcji
- 10. Jak dotknąć EditTextPrefences z innego działania lub innego wątku
- 11. Oczekiwanie połączeń googlemock z innego wątku
- 12. Drukowanie śledzenia stosu z innego wątku
- 13. Wywoływanie metod @Transactional z innego wątku (Runnable)
- 14. Rozszerzanie obserwowalnej tablicy nokautów
- 15. RavenDB Patch API: aktualizowanie zagnieżdżonej kolekcji
- 16. Uzyskanie wyniku śledzenia innego wątku
- 17. GUI nie zaktualizowano z innego wątku podczas korzystania z PyGtk
- 18. Uruchamianie kodu wewnątrz innego wątku w javascript
- 19. Blokada odblokowująca należąca do innego wątku java
- 20. Przechodzenie obiektów kolekcji z jednego wątku do drugiego w wątku Java
- 21. Zadanie ContinueWith() Nie aktualizowanie kursora przy użyciu wątku interfejsu użytkownika
- 22. Zapytanie i aktualizowanie właściwości w kolekcji przy użyciu LINQ
- 23. Zbieranie/aktualizowanie kolekcji za pomocą mybatis, jaka jest powszechna praktyka?
- 24. python asyncio, jak tworzyć i anulować zadania z innego wątku
- 25. Jak zaktualizować UI z innego wątku działającego w innej klasie
- 26. Wywołanie zapisanego obiektu Javy przez JNI z innego wątku
- 27. Zapisywanie stosu zapisu, gdy wyjątek jest generowany z innego wątku
- 28. Jak zakończyć lub zawiesić wątek Rust z innego wątku?
- 29. Niepoprawna operacja wątku: Kontrola uzyskana z wątku innego niż wątek, który został utworzony na
- 30. Użyj Unity API z innego wątku lub wywołaj funkcję w głównym wątku
możliwe duplikat [Aktualizacja ObservableCollection w oddzielnych nici] (http://stackoverflow.com/questions/2104614/updating-an-observablecollection-in-a-separate-thread) –
Wypróbuj poniższy link, który zapewnia bezpieczne dla wątków rozwiązanie, które działa z dowolnego wątku i może być powiązane za pośrednictwem wielu wątków interfejsu użytkownika: http://www.codeproject.com/Articles/64936/Multithreaded-ObservableImmutableCollection – Anthony