我一直在嘗試爲WPF應用程序編寫MVVM屏幕,使用異步&等待關鍵字爲1編寫異步方法。最初加載數據,2.刷新數據,3.保存更改並然後清爽。雖然我有這個工作,但代碼非常混亂,我不禁想到必須有更好的實現。任何人都可以建議一個更簡單的實現?MVVM異步等待模式
這是我的視圖模型的簡化版本:
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暴露到勢必繁忙指標的看法。
LoadDataAsync在第一次查看屏幕或按下刷新按鈕時由導航框架調用。此方法應同步設置IsLoading,然後將控制權返回給UI線程,直到服務返回數據。最後拋出任何異常,以便它們可以被全局異常處理程序捕獲(不需要討論!)。
SaveAync由按鈕調用,將更新後的值從表單傳遞到服務。它應該同步設置IsLoading,異步調用服務上的Save方法,然後觸發刷新。
你檢查了嗎? https://msdn.microsoft.com/en-us/magazine/dn605875.aspx。 – sam
是的,這是一篇很棒的文章。我不確定我喜歡綁定到Something.Result,儘管如此,感覺像ViewModel應該使它的狀態比這更明顯。 – waxingsatirical
只是一個想法嘗試...做一個標準的只有getter屬性和在等待的東西。使用IsAsync = true綁定。 – sam