繁体   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