Come posso inviare un evento PropertyChanged da un abbonamento a un IObservable basato su intervalli
-
25-09-2019 - |
Domanda
Ricevo un'eccezione "UnauthorizedAccesExpection - Accesso cross-thread non valido" quando provo a generare un evento PropertyChanged dall'interno di una sottoscrizione a una raccolta IObservable creata tramite Observable.Interval().
Con la mia conoscenza limitata del threading presumo che l'intervallo si stia verificando su qualche altro thread mentre l'evento vuole verificarsi sul thread dell'interfaccia utente???Sarebbe molto utile una spiegazione del problema.
Il codice assomiglia un po' a:
var subscriber = Observable.Interval(TimeSpan.FromSeconds(1))
.Subscribe(x =>
{
Prop = x; // setting property raises a PropertyChanged event
});
Qualche soluzione?
Modificare:
Questo codice viene eseguito da un ViewModel e non da un DependencyObject.
Soluzione
Modificare: Stavo confondendo SubscribeOn con ObserveOn.Ho aggiornato la mia risposta
Puoi risolvere il tuo problema inserendo il tuo intervallo nel thread del dispatcher:
var subscriber = Observable.Interval(TimeSpan.FromSeconds(1), Scheduler.Dispatcher)
.Subscribe(x =>
{
Prop = x; // setting property raises a PropertyChanged event
});
In alternativa, potresti essere in grado di utilizzare ObserveOnDispatcher
ma ciò comporterebbe il salto di thread, quindi lo sconsiglio:
var subscriber = Observable.Interval(TimeSpan.FromSeconds(1))
.ObserveOnDispatcher()
.Subscribe(x =>
{
Prop = x; // setting property raises a PropertyChanged event
});
Altri suggerimenti
Usa: -
var subscriber = Observable.Interval(TimeSpan.FromSeconds(1))
.Subscribe(x =>
{
Dispatcher.BeginInvoke(() => Prop = x);
});
Modifica
Dal momento che è necessario fare questo dal ViewModel vedere questo di Jeff Wilcox e il suo ottimo blog sul tema: proprietà cambia le notifiche per le applicazioni Silverlight multithread .