簡體   English   中英

將ICommand定義為異步lambda調用異步任務,還是只是async void?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM