实体框架核心:ToList()与ToListAsync()

时间:2018-10-01 09:58:41

标签: c# asp.net-core task-parallel-library

请考虑在ASP.NET Core Controller中使用异步GetAccountProperties方法:

public class CreditAccountController : Microsoft.AspNetCore.Mvc.Controller
{
    private readonly ICreditAccountManager _creditAccountManager;

    public CreditAccountController(
        ICreditAccountManager creditAccountManager
    {
        _creditAccountManager = creditAccountManager;
    }


    [HttpGet]
    public async Task<IActionResult> GetAccountProperties(...)
    {
        var result = await _creditAccountManager.GetPropertiesAsync(...);
        if (accountResult.Code == ResponseCode.Success)
            return Ok(result.Value);
        else 
            return NotFound();
    }
}

以及CreditAccountManager信息库中GetPropertiesAsync()方法的以下实现。

第一个实现使用.ToList()方法:

public Task<Result<List<GeneralAccount>>> GetAccountPropertiesAsync(...)
{
    var properties = _generalDatabaseContext.AccountProperties.Where(...).ToList();
    result.Code = ResponseCode.Success;
    result.Value = accounts;
    return Task.FromResult(result);
}

第二个方法使用.ToListAsync()方法和嵌套的async / await:

public async Task<Result<List<GeneralAccount>>> GetAccountPropertiesAsync(...)
{
    var properties = await _generalDatabaseContext.AccountProperties.Where(...).ToListAsync();
    result.Code = ResponseCode.Success;
    result.Value = accounts;
    return result;
}

考虑到存储库方法中没有其他EF调用,并且控制器的方法已经异步,那么在性能上哪种存储库方法实现更好?

1 个答案:

答案 0 :(得分:1)

就性能而言,ToListAsync的性能可能较差,因为异步总是会带来开销。

这并不是人们使用异步的真正原因。 由于您的数据库调用基本上是异步的,因此在同步选项中,服务器的线程会在完成其余工作并返回结果之前等待数据库调用完成。

在异步方法中,线程可以在等待数据库调用完成时处理其他请求。 因此,它提供了更好的吞吐量。 我会一直使用异步方法,因为将您的控制器动作标记为异步然后同步执行最大的IO操作是毫无意义的。

也就是说,考虑性能时最好的选择是测量。 进行一个同步的动作,另一个异步的动作。 然后测量各个请求的响应时间和吞吐量。 然后,您可以根据实际数字做出决定。