Próbowałem napisać ekran MVVM dla aplikacji WPF, używając asynchronicznego & czekać na słowa kluczowe, aby napisać metody asynchroniczne dla 1. Początkowo ładowanie danych, 2. Odświeżanie danych, 3. Zapisywanie zmian i następnie odświeżanie. Chociaż mam to działa, kod jest bardzo brudny i nie mogę przestać myśleć, że musi być lepsza implementacja. Czy ktoś może doradzić w sprawie prostszej implementacji?Async MVVM czeka na wzór
To jest wersja cut-dół mojego ViewModel:
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 narażona jest na widoku, w którym jest on związany ze wskaźnikiem zajętości.
LoadDataAsync jest wywoływana przez strukturę nawigacji po pierwszym wyświetleniu ekranu lub po naciśnięciu przycisku odświeżania. Ta metoda powinna synchronicznie ustawiać IsLoading, a następnie zwracać kontrolę do wątku interfejsu użytkownika, dopóki usługa nie zwróci danych. Wreszcie rzucając wszelkie wyjątki, aby mogły zostać przechwycone przez globalną obsługę wyjątków (nie do dyskusji!).
Funkcja SaveAync jest wywoływana za pomocą przycisku, przekazując zaktualizowane wartości z formularza do usługi. Powinien on synchronicznie ustawić IsLoading, asynchronicznie wywołać metodę Save w usłudze, a następnie uruchomić odświeżanie.
Czy to sprawdziłeś? https://msdn.microsoft.com/en-us/magazine/dn605875.aspx. – sam
Tak, to świetny artykuł. Nie jestem pewien, czy lubię wiązać się z Something.Result, ale czuję, że ViewModel powinien sprawić, że jego stan stanie się bardziej oczywisty. – waxingsatirical
Po prostu pomysł, aby spróbować ... Zrób standardową właściwość gettera i poczekaj na Coś. Powiąż używając IsAsync = true. – sam