Wie, um eine Funktion auszuführen, die auf einem hintergrund-thread für Windows Phone 7?
Ich bin mit MVVM-Light zu bauen, ein WP7 (Windows Phone 7) Anwendung. Ich wünschte, um all die arbeiten durchgeführt, die durch das Modell ausgeführt werden, auf einem hintergrund-thread. Dann, wenn die Arbeit getan ist, ein Ereignis auslösen, so dass die ViewModel kann die Daten verarbeiten.
Habe ich bereits herausgefunden, dass ich nicht einen Delegaten aufrufen, die asynchron von einer WP7 app.
Derzeit bin ich versuchen, mit ThreadPool.QueueUserWorkItem() zum ausführen von code auf einem hintergrund-thread und die Verwendung von MVVM Light DispatcherHelper.CheckBeginInvodeOnUI() zum auslösen eines Ereignisses im UI-thread, um zu signalisieren, das ViewModel, dass die Daten geladen wurden (dieses stürzt ab VS2010 und Blend 4, wenn Sie versuchen, anzeigen einer design-time-Ansicht).
Gibt es eine Beispiel-code zum ausführen von code auf einem hintergrund-thread und dann der Versand ein Ereignis zurück an den UI-thread für eine WP7 app?
Vielen Dank im Voraus,
Jeff.
Bearbeiten - Hier ein Beispiel-Modell
public class DataModel
{
public event EventHandler<DataLoadingEventArgs> DataLoadingComplete;
public event EventHandler<DataLoadingErrorEventArgs> DataLoadingError;
List<Data> _dataCasch = new List<Data>();
public void GetData()
{
ThreadPool.QueueUserWorkItem(func =>
{
try
{
LoadData();
if (DataLoadingComplete != null)
{
//Dispatch complete event back to the UI thread
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
//raise event
DataLoadingComplete(this, new DataLoadingEventArgs(_dataCasch));
});
}
}
catch (Exception ex)
{
if (DataLoadingError != null)
{
//Dispatch error event back to the UI thread
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
//raise error
DataLoadingError(this, new DataLoadingErrorEventArgs(ex));
});
}
}
});
}
private void LoadData()
{
//Do work to load data....
}
}
InformationsquelleAutor der Frage Jeff R | 2010-07-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist, wie ich Ansatz eine Lösung für dieses.
Ihre ViewModel implementiert die INotifyPropertyChanged-Recht? Es gibt keine Notwendigkeit zum auslösen des Events. Nur heben Sie Sie "blank" in das Modell, dann der Versand der RaisePropertyChanged im ViewModel.
Und ja, Sie sollten haben eine Art von singleton-Modell/Datenbank im code. Nach allem, was ist eine SQL-Datenbank, wenn nicht eine gigantische singleton? Da wir nicht über eine Datenbank verfügen, in WP7, scheuen Sie sich nicht, das erstellen einer singleton-Objekt. Ich habe eine sogenannte "Datenbank" 🙂
Ich habe einfach versucht, threading mein dataloads gibt, und erkennen, dass in der Tat der beste Ansatz ist einfach, die Implementierung von INotifyPropertyChanged rechts unten auf der Modell-Ebene. Es ist keine Schande in diesem.
So, hier ist was ich mache in der singleton-Objekt zur Datenbank zu laden und die Rücksendung meiner Touren "Tabelle" (Hinweis: die thread.Schlaf zu machen, nehmen Sie eine sichtbare Menge an Zeit zum laden, normalerweise unter 100ms). Datenbank-Klasse jetzt implementiert INotifyPropertyChanged und löst Ereignisse aus, wenn das laden abgeschlossen ist:
Kannst du Folgen? Ich bin Deserialisieren der Tour-Liste auf einem hintergrund-thread, dann heben Sie ein propertychanged-Ereignis.
Nun in das ViewModel, ich möchte eine Liste von TourViewModels zu binden, die ich wählen Sie mit einer linq-Abfrage, sobald ich sehe, dass die Touren-Tabelle geändert hat. Es ist wohl etwas Billig zu hören, für die Datenbank ein Ereignis in der ViewModel - es könnte "schöner" zu Kapseln, der in das Modell, aber lassen Sie uns nicht machen, wir arbeiten, wir müssen das nicht eh?
Haken Sie die Datenbank-Ereignis in der Viewmodel-Konstruktor:
Hören für die entsprechende Tabelle ändern (wir lieben magic strings! 😉 ):
Wählen Sie die Datensätze möchte ich aus der Tabelle, dann sagen Sie der Ansicht gibt es neue Daten:
Und schließlich, in Ihrem ViewModelBase, es ist am besten, um zu überprüfen, ob Ihre RaisePropertyChanged Bedürfnisse Disposition. Meine "SafeDispatch" - Methode ist so ziemlich die gleiche wie die von MVVMlight:
Diese funktioniert einwandfrei in meinem code, und ich denke, ist ziemlich aufgeräumt?
Schließlich extra für die Experten: in WP7, es könnte gut sein, um hinzuzufügen eine ProgressBar mit IsIndeterminate=True auf Ihrer Seite - dies zeigt die "gepunktete" progress bar. Dann, was Sie tun können, ist, wenn das ViewModel zuerst lädt man könnte eine "ProgressBarVisible" - Eigenschaft Sichtbar (und heben Sie die zugehörigen PropertyChanged-Ereignis). Binden Sie die ProgressBar-Sichtbarkeit dieses ViewModel-Eigenschaft. Wenn die Datenbank PropertyChanged-Ereignis ausgelöst wird, legen Sie die visibility auf Collapsed, um die progressbar Weg.
Diese Weise wird der Benutzer sehen, der "IsIndeterminate" Fortschrittsbalken an der Spitze der Bildschirm, während der Deserialisierung ausgeführt wird. Schön!
InformationsquelleAutor der Antwort Ben Gracewood
Habe ich nicht entwickelt für WP7 vor, aber ich fand diese Artikel, die nützlich sein könnten!
Hier ist der Speisesaal Philosoph Beispielcode aus dem Artikel, dass sollte Ihnen eine gute Idee, wie man ein Ereignis auslösen, um die Benutzeroberfläche von einem anderen thread:
Ich hoffe, es ist hilfreich :).
Eins, das ist verwirrend: Sie sagte, wenn Sie den Helfer, um das Ereignis auslösen, dann VS2010 stürzt ab... was genau sind Sie zu sehen, wenn es abstürzt? Sind Sie eine Ausnahme?
InformationsquelleAutor der Antwort Kiril
Jeff, ich bin immer noch herauszufinden, dieses Zeug aus mir. Ich habe eine ähnliche Frage und endete Beantwortung es mir durch den Bau eines einfachen Beispiels. Hier:
Eine super-simple MVVM-Light WP7 Probe?
Die Zusammenfassung ist:
1) ich mein Modell abgeleitet (ja mein Modell) aus
ViewModelBase
. Das gibt mir Mvvm-Light ist die Implementierung von messaging-undINotifyPropertyChanged
was praktisch ist. Man könnte argumentieren, das ist nicht "rein", aber ich glaube nicht, dass es darauf ankommt.2) ich habe Mvvm-Light
DispatcherHelper.CheckBeginInvokeOnUI
Helfer genauso, wie Sie es getan hat (von meinem Modell, NICHT mein ViewModel).Hoffe, das hilft.
InformationsquelleAutor der Antwort tig