[英]Define ICommand as async lambda calling async Task, or just async void?
考慮以下兩種設置ICommand以執行異步任務的方法(在這種情況下,使用Xamarin.Forms.Command
,但我希望這並不重要):
場景1:將命令設置為等待async Task
方法的異步lambda:
// Command definition
ToggleCheckedCommand = new Command(
execute: async () => { await ToggleCheckedAsync(); },
canExecute: () => !IsBusy);
// Method that is executed
private async Task ToggleCheckedAsync()
{
IsBusy = true;
await DoWork();
IsBusy = false;
}
場景2:將命令設置為async void
方法:
// Command definition
ToggleCheckedCommand = new Command(
execute: ToggleCheckedAsync,
canExecute: () => !IsBusy);
// Method that is executed
private async void ToggleCheckedAsync()
{
IsBusy = true;
await DoWork();
IsBusy = false;
}
只要一個人永遠不會直接調用ToggleCheckedAsync
,這兩個場景是否相同,或者與另一個相比,是否存在任何問題?
(我知道async void
在直接事件處理程序之外通常被認為是一種不好的做法,但是ToggleCheckedAsync
在邏輯上是一個事件處理程序,而方案1中的async lambda也是AFAIK有效的async void
。)
只要一個人永遠不會直接調用ToggleCheckedAsync,這兩個場景是否相同,或者與另一個相比,是否存在任何問題?
任何一個都沒事; 他們是等同的方法。 async void
在這里是合適的,因為ICommand.Execute
在邏輯上是一個事件處理程序。 (不要誤會: 有一個async void
在這兩種方法:第一個例子中的拉姆達變得async void
)。
但是,在我自己的代碼中,這不成立:
只要一個人永遠不會直接調用ToggleCheckedAsync
特別是單元測試。 單元測試可以直接執行命令,包括能夠await
它們完成,並且ICommand
不滿足這種需要。
因此,我發現公開async Task
方法很有用。 或者,如果您想獲得更好的功能,請使用Task ExecuteAsync
方法開發IAsyncCommand
類型,並從ViewModel中公開它 。 將該設計作為其邏輯結論,您最終可以使用完整的AsyncCommand
來隱藏async void Execute
作為實現細節 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.