[英]Async await in MVVM XAML Applications
我試着理解如何在我的ViewModel中使用async / await模式接收初始數據。 我們來看看代碼:
public interface IPeopleService
{
Task<IEnumerable<Person> GetPeopleAsync();
}
public MainViewModel
{
public ObservableCollection<Person> People{get;set;}
public MainViewModel(IPeopleService peopleService)
{
LoadMyData(peopleService);
}
public async Task LoadMyData(IPeopleService peopleService)
{
try
{
People = await peopleService.GetPeopleAsync();
}
catch(Exception e)
{
//log
//notify user
}
}
}
PeopleService包含People Data的異步方法。 注入IOC(無論如何)。 之后我調用異步操作LoadMyData(以防止阻塞UI,因此沒有await關鍵字),並且在該方法中,我從服務中調用異步操作來捕獲所有異常並且不對用戶進行操作。 這種方法有什么問題?
我從msdn閱讀文章: https : //msdn.microsoft.com/en-us/magazine/dn605875.aspx當我注意到為這種任務創建一個泛型類並更改我的所有屬性以將該類用作泛型參數,更改XAML Bindings以接收Property.Result屬性,我認為這很瘋狂並且在項目中造成了很大的混亂。 此外,ViewModel中的屬性指定此屬性是異步的,在我看來是糟糕的設計。 什么是最簡單的方法來解決我的問題? 我的解決方案是否可以保持簡單?
之后我調用異步操作LoadMyData(以防止阻塞UI,因此沒有await關鍵字),並且在該方法中,我從服務中調用異步操作來捕獲所有異常並且不對用戶進行操作。 這種方法有什么問題?
加載數據時不會阻止您的UI。 那很好。 但異步數據加載會帶來一些問題:在加載數據時UI會顯示什么? UI如何向用戶顯示錯誤?
在當前代碼中,UI列表在加載數據時只是空的。 IMO應至少具有“加載”類型的狀態,因此用戶可以區分空結果集和仍在進行中的操作。 此外,我假設您的notify user
代碼是通過代碼而不是通過數據綁定來打開對話框或其他內容。 IMO錯誤指示器優於模態對話框。
NotifyTaskCompletion<T>
背后的目的是它充當數據綁定異步操作。 因此,您可以使用其屬性更改為“加載”和“錯誤”狀態。 這就是為什么你的綁定必須改為.Result
- 因為你綁定到異步操作的結果 。 如果您不想顯示“加載”指示器並且您不希望通過數據綁定顯示錯誤,那么是的, NotifyTaskCompletion<T>
將是過度的。
這取決於你想要做多少數據綁定。 如果你對代碼感到滿意,那就沒關系了:
public async Task LoadMyData(IPeopleService peopleService)
{
try
{
... // Hide people display
... // Show loading indicator
People = await peopleService.GetPeopleAsync();
... // Show people display
}
catch(Exception e)
{
... // Show error indicator
}
finally
{
... // Hide loading indicator
}
}
或者,您可以使用數據綁定完成所有操作,這使您的代碼更簡單:
// (wrapped in NotifyTaskCompletion)
public async Task LoadMyData(IPeopleService peopleService)
{
People = await peopleService.GetPeopleAsync();
}
我已經完成了兩種方式,但如果我有一個執行大量異步操作的項目,我傾向於NotifyTaskCompletion<T>
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.