簡體   English   中英

如何將 void 同步方法轉換為異步方法?

[英]How to convert a void synchronous method to async method?

所以我有這個只有同步操作的方法:

public void Foo(){
    //do something synchronously
    if(x == 0)
        return;
    else if(x < 5):
        //do something
        return;
    // do something extra
}

由於一些接口更改,該方法必須更改為異步,盡管沒有異步操作。 為了擁有 async 關鍵字,它的主體中必須有一個await關鍵字。 原始同步方法的等效方法是:

public async Task FooAsync(){
    //do something synchronously
    if(x == 0)
        await Task.CompletedTask;
    else if(x < 5):
        //do something
        await Task.CompletedTask;
    // do something extra
}

我不確定這一點,因為CompletedTask屬性表明它是一個成功的操作,但並非所有這些條件都是如此。

編輯:在評論中解決。 僅僅因為一個方法用“async”后綴表示,並不意味着它需要一個async修飾符。 function 將按如下所示編寫以遵守接口更改:

public Task FooAsync(){
    //do something synchronously
    if(x == 0)
        return Task.CompletedTask;
    else if(x < 5):
        //do something
        return Task.CompletedTask;
    // do something extra
    return Task.CompletedTask;
}

正如其他人所指出的,類似任務的返回類型是異步簽名,而async是異步實現細節 完全有可能讓Task返回方法不是async

但是,有一個重要的警告:例外。 當異步(即類似Task返回)方法失敗時,預期的語義是捕獲異常並將其放置在返回的任務上。

因此,您不想只返回CompletedTask 您還想捕獲異常並使用Task.FromException

public Task FooAsync()
{
  try
  {
    //do something synchronously
    if(x == 0)
        return Task.CompletedTask;
    else if(x < 5):
        //do something
        return Task.CompletedTask;
    // do something extra
    return Task.CompletedTask;
  }
  catch (Exception ex)
  {
    return Task.FromException(ex);
  }
}

在這一點上,有相當多的樣板。 您可能更喜歡使用async而不使用await ,例如:

#pragma warning disable 1998
public async Task FooAsync()
#pragma warning restore 1998
{
    //do something synchronously
    if(x == 0)
        return;
    else if(x < 5):
        //do something
        return;
    // do something extra
}

這種方法的問題是你會得到編譯器警告,除非你包含丑陋的編譯指示來禁用它們。 如果您發現自己需要在多個地方執行此操作,我建議您使用一些輔助方法( 從我的 AsyncEx 庫中竊取):

public static class TaskHelper
{
#pragma warning disable 1998
    public static async Task ExecuteAsTask(Action func)
#pragma warning restore 1998
    {
        func();
    }

#pragma warning disable 1998
    public static async Task<T> ExecuteAsTask<T>(Func<T> func)
#pragma warning restore 1998
    {
        return func();
    }
}

像這樣使用:

public Task FooAsync() => TaskHelper.ExecuteAsTask(() =>
{
    //do something synchronously
    if(x == 0)
        return;
    else if(x < 5):
        //do something
        return;
    // do something extra
});

它允許您快速輕松地包裝同步方法。

暫無
暫無

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

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