简体   繁体   English

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

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

So I have this method that has only synchronous operations:所以我有这个只有同步操作的方法:

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

Due to some interface changes, that method has to be changed to asynchronous, despite having no async operations.由于一些接口更改,该方法必须更改为异步,尽管没有异步操作。 And in order to have the async keyword, there must be an await keyword within its body.为了拥有 async 关键字,它的主体中必须有一个await关键字。 Would an equivalent method of the originally synchronous method be:原始同步方法的等效方法是:

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
}

I'm not sure about this since the CompletedTask property indicates that it is a successful operation, which isn't the case for all these conditionals.我不确定这一点,因为CompletedTask属性表明它是一个成功的操作,但并非所有这些条件都是如此。

EDIT: Resolved in comments.编辑:在评论中解决。 Just because a method is denoted with an "async" suffix it does not mean that it needs an async modifier.仅仅因为一个方法用“async”后缀表示,并不意味着它需要一个async修饰符。 The function would be written as shown below to adhere to interface changes: 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;
}

As others have noted, a task-like return type is an asynchronous signature , whereas async is an asynchronous implementation detail .正如其他人所指出的,类似任务的返回类型是异步签名,而async是异步实现细节 It's entirely possible to have a Task -returning method not be async .完全有可能让Task返回方法不是async

However, there is one important caveat: exceptions.但是,有一个重要的警告:例外。 When an asynchronous (ie, Task -like-returning) method fails, the expected semantics is to capture the exception and place it on the returned task.当异步(即类似Task返回)方法失败时,预期的语义是捕获异常并将其放置在返回的任务上。

So, you wouldn't want to just return CompletedTask ;因此,您不想只返回CompletedTask you'd also want to capture exceptions and use Task.FromException :您还想捕获异常并使用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);
  }
}

At this point, there's rather a bit of boilerplate.在这一点上,有相当多的样板。 You may prefer to use async without await , as such:您可能更喜欢使用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
}

The problem with that approach is that you will get compiler warnings unless you include the ugly pragmas to disable them.这种方法的问题是你会得到编译器警告,除非你包含丑陋的编译指示来禁用它们。 If you find yourself needing to do this in several places, I would recommend using some helper methods ( stolen from my AsyncEx library ):如果您发现自己需要在多个地方执行此操作,我建议您使用一些辅助方法( 从我的 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();
    }
}

used as such:像这样使用:

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

which allows you to wrap synchronous methods quickly and easily.它允许您快速轻松地包装同步方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM