返回 Task.FromResult 或仅返回异步代码中的值

Returning Task.FromResult or just value in async code

考虑这段代码:

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

似乎当您输入异步方法时,编译器有一个状态机来跟踪您当前的堆栈。

现在我的问题是 ReturnTaskReturnTask2 哪个更好?因为 ReturnTask2 不需要创建一个新的状态机来只是 return 一个微不足道的值。

我应该在进入异步方法之前直接执行 returns 还是 ReturnTask 就足够了,这可能是过度优化。我实际上已经查看了 IL 代码,看起来编译器似乎没有进行任何优化来避免使用此状态机。

两种实现方式都很好。它们的功能肯定相同。

是的,您通过不将方法标记为 async 来避免状态机。如果您正在处理 极其 性能敏感的代码,那可能很重要。在大多数情况下(你正在处理异步)这不太重要。毕竟,可以重写 any async 方法以避免状态机。您只需支付一小笔费用(每个方法调用创建一个 class 的实例)以换取(可能)使该方法更容易 write/read。对于 非常 简单的异步方法 async 实际上并没有帮助使方法更容易 read/write,在这种情况下不需要支付成本。当您实际利用状态机的功能并使方法更易于编写时,几乎总是值得(通常可以忽略不计的)性能成本。

因此,如果编写非异步方法对您来说同样容易,请继续使用它。如果您认为 async 方法的便利性正在为您增加价值,请使用它。