Sto scrivendo un'applicazione per Windows Store App per Windows 8. Ha solo una pagina xaml con TextBlock
. La pagina ha la MyTimer classe come DataContext
:Aggiornamento dell'interfaccia utente di Windows Store App
this.DataContext = new MyTimer();
MyTimer
implementa INotifyPropertyChanged
e l'aggiornamento della proprietà Time
è fatto con un timer:
public MyTimer(){
TimerElapsedHandler f = new TimerElapsedHandler(NotifyTimeChanged);
TimeSpan period = new TimeSpan(0, 0, 1);
ThreadPoolTimer.CreatePeriodicTimer(f, period);
}
con
private void NotifyTimeChanged(){
if (this.PropertyChanged != null){
this.PropertyChanged(this, new PropertyChangedEventArgs("Time"));
}
}
il TextBlock
ha un data base sul tempo
<TextBlock Text="{Binding Time}" />
Quando eseguo l'applicazione ho la seguente eccezione:
System.Runtime.InteropServices.COMException was unhandled by user code
Con il messaggio
The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
Il vero problema è che sto aggiornando la proprietà del MyTimer di classe, non la stessa GUI, Non riesco a capirlo, ma penso che la soluzione dovrebbe usare qualcosa come this one.
Grazie mille. Questo mi suggerisce che dovrò usare SynchronizationContext ogni volta che uso una chiamata asincrona ... penserò a fare qualcosa di simile anche con la parola chiave asincrona. – Gabber
Sì, se stai utilizzando la parola chiave C# 4.5, attendi questo per impostazione predefinita. –
Grazie per la risposta!Voglio solo aggiungere un sidenote: se vuoi richiamare nel contesto dell'interfaccia utente, assicurati di catturare il 'SynchronizationContext' non prima che l'UI sia stato compilato (io uso il gestore di eventi' OnLaunched' per farlo), altrimenti il contesto che afferri non servirà. Ulteriori letture: http://www.codeproject.com/Articles/31971/Understanding-SynchronizationContext-Part-I – Lvsti