簡體   English   中英

'async void'對於事件處理程序是可以的,但如果只有一個虛擬方法可以覆蓋怎么辦?

[英]'async void' is okay for event handlers, but what if there is only a virtual method to override?

我們的團隊使用Caliburn ,視圖模型派生自一個提供虛擬方法覆蓋的基類。 例如,只要激活視圖,就可以覆蓋OnActivate() Caliburn不提供附加的事件處理程序。 我們想在OnActivate()調用等待函數。 這可以通過以下方式完成:

protected override async void OnActivate()
{
    base.OnActivate();
    try
    {
        await DoSomethingAsync()           
    }
    catch (Exception ex)
    {
  // …
    }
}

盡管一切正常,但我們與最佳實踐相沖突,即async void只能應用於事件處理程序。 但是,沒有事件處理程序,只有一個要覆蓋的虛方法。 Sonarqube注意到這一點並發出警告。

解決這個問題的最佳方法是什么?

正如你已經想到的那樣,這不是最好的做法,雖然它“似乎”好像一切正​​常 - 但事實並非如此......你正在為自己設置很多挫折感。

解決這個問題的最佳方法是什么?

最佳方法取決於您嘗試完成的所需功能以及所述功能可能需要多長時間,以及是否還有其他任何特定依賴於此功能的方法。 一位聰明人曾經說過,“一路走async或一路sync ”。 我同意那個!

有些人可能會覺得有必要向你解釋在這種情況下sync async sync是安全的,但是他們會把最佳實踐模型推得太遠。

與最佳實踐一致我只會使用async / await如果我覆蓋的virtual方法是TaskTask<T>或其他“awaitable”類型返回簽名。

話雖如此,如果這是絕對必要的,我會將任務作為屬性存儲,並允許依賴它的其他調用await它。

public Task MyTask;

protected override void OnActivate()
{
    base.OnActivate();
    try
    {
        MyTask = DoSomethingAsync()           
    }
    catch (Exception ex)
    {
        // …
    }
}

然后在其他地方,無論是在這個類中還是在它外部 - 如果有代碼依賴於它完成,你可以await那里await它。

async Task ConsumingAsync()
{
    await _instance.MyTask;

    // Now we know the work is done...
}

同樣,這不是我建議做的事情。 我懇請你考慮替代方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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