2015-02-23 85 views
9

我想了解什麼是調用異步方法更新我的ViewModel時使用的最佳方法。 現在,讓我們說我有這樣的事情:使用MVVM模式實現異步「loadData」方法的最佳方法

查看:

private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) 
{ 
    //Call my ViewModel method to update the data the UI is bound to   
} 

視圖模型:

public async Task loadData() 
{ 
    this.Source = await loadStuffFromDatabaseAsync(); 
} 

現在,我不知道這下面的一個我應該使用的方法:

1)在我LoadState的方法,使用方法:

await Task.Run(async() => { await ViewMode.loadData(); }); 

2)使用 Task.Run 而不等待 行動 內 loadData 方法:

await Task.Run(() => { ViewModel.loadData(); }); 

3)呼叫我的 loadData 方法:

await ViewModel.loadData().ConfigureAwait(false); 

4)調用 loadData 方法,無需等待它在我的 View類 和使用 Task.Run 我loadData方法中:

查看:

private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) 
{ 
    ViewModel.loadData(); 
} 

查看型號:

public async void loadData() 
{ 
    await Task.Run(async() => 
    { 
     this.Source = await loadStuffFromDatabaseAsync(); 
    }); 
} 

這些認可的主要區別是什麼?

另一個更有效率,我應該特別選擇一個嗎?

感謝您的幫助! :)

塞爾吉奧

+0

異步void的方法,你應該遵循附加異步所有異步方法的命名約定。 – 2015-02-23 20:35:01

+0

我認爲,由於Asynch支持集成到基本代碼中的是Async和Await兩個詞,因此我相信Reed Cosby已經告訴我們所有我們需要的東西。我們不再需要調用任務方法。 – 2015-02-23 20:51:40

+2

@JohnPeters:事實並非如此。可能有阻塞UI線程的代碼。 – Fred 2015-02-23 21:25:18

回答

2

,才應使用Task.Run,如果你有CPU綁定或阻塞,你要搬出去,UI線程的工作。這不是這種情況,所以直接電話(選項3)是最自然的。

以它們依次是:

await Task.Run(async() => { await ViewMode.loadData(); }); 

此選項將在一個線程池線程執行loadData。這可能不太好,因爲loadData正在更新UI(間接通過設置VM屬性)。即使它確實發生了工作(即,某些MVVM框架可以在某些情況下正確處理來自後臺線程的更新),但可能不必要,因爲loadData是一種異步方法。

此外,它無故增加了狀態機開銷async

await Task.Run(() => { ViewModel.loadData(); }); 

此選項都是一樣的問題,只是因爲它不具備async狀態機的開銷,這會更有效。但它仍然在後臺線程上更新虛擬機屬性,並且不必要地使用後臺線程。

public async void loadData() 

這是最糟糕的。它繼承了其他問題:在後臺線程上更新VM屬性並使用不必要的後臺線程。爲此它增加了async void的問題。一個問題是NavigationHelper_LoadState無法捕捉到來自loadData的任何異常。另一個問題是loadData不容易測試。

所以只需使用簡單的方法,直接把它叫做:應避免

await ViewModel.loadData().ConfigureAwait(false); 
+0

謝謝你的回答!我只是有一個疑問:你說我應該只使用Task.Run進行CPU綁定或阻塞工作:爲什麼不從數據庫中加載數據作爲阻塞工作?由於它是一個IO操作,可能需要很長時間才能完成,因此阻止正在等待該任務的調用方法? – Sergio0694 2015-02-23 22:40:12

+1

線程未被阻止,因爲它是異步操作。 – 2015-02-23 23:15:44

+0

你是對的,通過「阻止工作」你的意思是一些同步代碼運行。再次感謝你的幫助 :) – Sergio0694 2015-02-23 23:19:46

相關問題