考虑以下代码:
class Program
{
public async Task<int> ReturnTask(bool value)
{
if (!value)
{
return 3;
}
return await ReturnTaskImp();
}
public Task<int> ReturnTask2(bool value)
{
if (!value)
{
return Task.FromResult(3);
}
return ReturnTaskImp();
}
public async Task<int> ReturnTaskImp()
{
Task.Delay(3000); //do some really heavy work
return 2; //return some value after heavy work done
}
static void Main(string[] args)
{
var p = new Program();
var t1 = p.ReturnTask(true).Result; //I know bad but not important now.
var t2 = p.ReturnTask(false).Result;
}
}
我刚读完this
似乎当你输入一个异步方法时,编译器有一个状态机来跟踪你当前的堆栈。
现在我的问题在于哪一个会更好ReturnTask
或ReturnTask2
?由于ReturnTask2
不需要创建新的状态机来返回一个微不足道的值。
我应该在进入异步方法之前进行直接返回,还是ReturnTask
足够,这可能是过度优化。我实际上看过IL代码,看起来编译器没有做任何优化以避免使用这个状态机。
答案 0 :(得分:1)
两种实现都很好。它们当然具有相同的功能。
是的,您通过不将方法标记为async
来避开状态机。如果您正在处理可能很重要的极性能敏感代码。在大多数情况下(你根本就处理异步),这不太重要。毕竟,任何 async
方法都可以重写,以避免状态机。您需要支付少量费用(为每个方法调用创建一个类的实例)以换取(可能)使该方法更易于编写/读取。对于非常简单的异步方法async
实际上并没有帮助使该方法更容易读/写,在这种情况下,不需要支付成本。当您实际利用状态机的功能并使该方法更易于编写时,几乎总是值得(通常可忽略不计)性能成本。
因此,如果编写非异步方法对您来说同样容易,请继续使用它。如果您认为async
方法的便利性为您增加了价值,请使用它。