我有一个虚方法,有时包含await调用,有时不包含。IDE会给我警告,应该如何正确处理?
在我的基类中:
protected virtual async Task GoNext ()
它从基类中通过await被调用。
然后在我的子类中,我覆盖了这个方法,但有时会包含await,有时则不会。
我有一个虚方法,有时包含await调用,有时不包含。IDE会给我警告,应该如何正确处理?
在我的基类中:
protected virtual async Task GoNext ()
它从基类中通过await被调用。
然后在我的子类中,我覆盖了这个方法,但有时会包含await,有时则不会。
async
关键字实际上并不是继承方法签名的一部分,而更像是向编译器发出的一个信号,告诉它需要根据异步方法的模式进行编译和重写方法。
因此,如果继承的方法没有使用await
关键字,您可以省略async
关键字。
请注意,您仍然必须返回一个Task
或Task<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>
的方式,显然不需要像我上面那样对结果进行包装。
async
不是继承的方法签名的一部分。如果要声明一个重写方法而不使用await
,则不需要编写async
。但是您仍然需要返回一个Task
或Task<T>
。请贴出展示问题及实际警告的一些代码,以确保问题的具体情况不会引起混淆。 - Lasse V. Karlsen