c# - 如何将 void 同步方法转换为异步方法?

标签 c# async-await

所以我有这个只有同步操作的方法:

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

由于一些接口(interface)更改,该方法必须更改为异步,尽管没有异步操作。为了使用 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 修饰符。该函数将编写如下,以遵循接口(interface)更改:

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 返回方法完全有可能不是异步

但是,有一个重要的警告:异常(exception)情况。当异步(即Task-like-returning)方法失败时,预期的语义是捕获异常并将其放置在返回的任务上。

因此,您不想只返回 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
}

这种方法的问题是,除非您包含丑陋的编译指示来禁用它们,否则您将收到编译器警告。如果您发现自己需要在多个地方执行此操作,我建议使用一些辅助方法( stolen from my AsyncEx library ):

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
});

它允许您快速轻松地包装同步方法。

关于c# - 如何将 void 同步方法转换为异步方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65602619/

相关文章:

c# - 在 WebService 中找不到 Windows Azure 管理证书

c# - 错误无法从程序集 'dotless.Core,版本 = 1.5.3.0 加载类型 'dotless.Core.configuration.WebConfigConfigurationLoader'

c# - 如何在线程或任务中进行异步操作

C# 如何等待返回 Task<dynamic> 的方法?

c# - 使用 async await 处理 Web 请求的超时

javascript - 函数在await执行完成之前返回

c# - 对 ip 范围的多个 HttpClient 异步请求

c# - 使用 TreeView 的主视图/详细 View

c# - 为什么 Resharper 无法识别我的网络引用?

C# 比较速记