Ich habe versucht, einen MVVM-Bildschirm für eine WPF-Anwendung zu schreiben, mit den asynchronen & erwarten Schlüsselwörter zu schreiben asynchrone Methoden für 1. Anfängliches Laden von Daten, 2. Aktualisieren der Daten, 3. Speichern von Änderungen und dann erfrischend. Obwohl ich funktioniere, ist der Code sehr unordentlich und ich kann mir nicht helfen zu denken, dass es eine bessere Implementierung geben muss. Kann jemand eine einfachere Implementierung empfehlen?MVVM Async erwarten Muster
Dies ist eine abgespeckte Version meiner Ansichtsmodell:
public class ScenariosViewModel : BindableBase
{
public ScenariosViewModel()
{
SaveCommand = new DelegateCommand(async() => await SaveAsync());
RefreshCommand = new DelegateCommand(async() => await LoadDataAsync());
}
public async Task LoadDataAsync()
{
IsLoading = true; //synchronously set the busy indicator flag
await Task.Run(() => Scenarios = _service.AllScenarios())
.ContinueWith(t =>
{
IsLoading = false;
if (t.Exception != null)
{
throw t.Exception; //Allow exception to be caught on Application_UnhandledException
}
});
}
public ICommand SaveCommand { get; set; }
private async Task SaveAsync()
{
IsLoading = true; //synchronously set the busy indicator flag
await Task.Run(() =>
{
_service.Save(_selectedScenario);
LoadDataAsync(); // here we get compiler warnings because not called with await
}).ContinueWith(t =>
{
if (t.Exception != null)
{
throw t.Exception;
}
});
}
}
IsLoading zur Ansicht freigelegt wird, wo es an einer viel befahrenen Indikator gebunden ist.
LoadDataAsync wird vom Navigationsframework aufgerufen, wenn der Bildschirm zum ersten Mal angezeigt wird oder wenn eine Aktualisierungsschaltfläche gedrückt wird. Diese Methode sollte IsLoading synchron festlegen und anschließend die Steuerung an den UI-Thread zurückgeben, bis der Dienst die Daten zurückgegeben hat. Abschließend werden alle Ausnahmen ausgelöst, damit sie vom globalen Ausnahme-Handler abgefangen werden können (nicht zur Diskussion!).
SaveAync wird über eine Schaltfläche aufgerufen und übergibt aktualisierte Werte aus einem Formular an den Dienst. Es sollte synchron IsLoading festlegen, die Save-Methode für den Dienst asynchron aufrufen und dann eine Aktualisierung auslösen.
Hast du das überprüft? https://msdn.microsoft.com/en-us/magazine/dn605875.aspx. – sam
Ja, es ist ein toller Artikel. Ich bin mir nicht sicher, ob ich es mag, an Something.Result zu binden, aber ich habe das Gefühl, dass das ViewModel seinen Zustand deutlicher machen sollte. – waxingsatirical
Nur eine Idee zu versuchen ... Machen Sie eine Standard-Getter-Eigenschaft und warten auf etwas warten. Binden mit IsAsync = true. – sam