不需要 await 调用的 Async/Await

13

我有一个虚方法,有时包含await调用,有时不包含。IDE会给我警告,应该如何正确处理?

在我的基类中:

protected virtual async Task GoNext ()

它从基类中通过await被调用。

然后在我的子类中,我覆盖了这个方法,但有时会包含await,有时则不会。


5
我不理解这个问题。async不是继承的方法签名的一部分。如果要声明一个重写方法而不使用await,则不需要编写async。但是您仍然需要返回一个TaskTask<T>。请贴出展示问题及实际警告的一些代码,以确保问题的具体情况不会引起混淆。 - Lasse V. Karlsen
如果方法中没有使用 await 关键字,你不能省略 async 关键字吗? - Stefan
1
你可以提供一些你找到的例子,这样会让问题更好理解。 - Amit Kumar Ghosh
1个回答

21

async关键字实际上并不是继承方法签名的一部分,而更像是向编译器发出的一个信号,告诉它需要根据异步方法的模式进行编译和重写方法。

因此,如果继承的方法没有使用await关键字,您可以省略async关键字。

请注意,您仍然必须返回一个TaskTask<T>,那部分是继承方法签名的一部分。

因此,这将给您一个警告:

class Base
{
    public virtual async Task<int> Method()
    {
        await Task.Delay(10);
        return 42;
    }
}

class Derived : Base
{
    // next line produces warning
    public override async Task<int> Method()
    {
        return 42;
    }
}

警告是:

警告:CS1998 此异步方法缺少 'await' 操作符,将以同步方式运行。请考虑使用 await 操作符等待非阻塞 API 调用,或者使用 await Task.Run(...) 在后台线程上执行 CPU 绑定工作。

然而,这将不会产生警告:

class Derived : Base
{
    public override Task<int> Method()
    {
        return Task.FromResult(42);
    }
}

请注意我更改了上一个方法中的return语句,因为async关键字带来的"魔法"之一是自动将返回值包装在Task<T>中。如果您有其他获取Task<T>的方式,显然不需要像我上面那样对结果进行包装。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接