使用EF Core时,异步调用比同步慢

时间:2018-09-25 00:22:00

标签: c# entity-framework asp.net-core async-await ef-core-2.1

任何知道为什么这段代码需要49毫秒

public void OnGet(String sessionId)
{
    BackgroundEntry =  _context.BackgroundEntry.Where(x => x.Id == sessionId).ToList();
}

但是此代码需要300毫秒以上的时间?

public async Task OnGetAsync(String sessionId)
{
    BackgroundEntry = await _context.BackgroundEntry.Where(x => x.Id == sessionId).ToListAsync();
}

我希望两者都在同一时间。 在各种条件下进行了测试,并且始终保持不变,异步具有300毫秒以上的延迟。

BackgroundEntry由EF自动生成:

public partial class BackgroundEntry
{
    public string Id { get; set; }
    public string Part { get; set; }
    public long Datetime { get; set; }
    public DateTime CreatedAt { get; set; }
    public Guid Session { get; set; }
    public string Action { get; set; }
    public string Domain { get; set; }
    public string Location { get; set; }
    public long? LastEntryDatetime { get; set; }

    public BackgroundEntry BackgroundEntryNavigation { get; set; }
    public BackgroundEntry InverseBackgroundEntryNavigation { get; set; }
}

带有秒表的基准

        using (Models.RecorderContext context = new Models.RecorderContext())
        {
            sw.Start();
            var BackgroundEntry = context.BackgroundEntry.Where(x => x.Id == sessionId).ToList();
            sw.Stop();
        }

        var g = sw.ElapsedMilliseconds;

        sw.Reset();
        // g = 22 ms

        using (Models.RecorderContext context = new Models.RecorderContext())
        {
            sw.Start();
            var BackgroundEntry = await context.BackgroundEntry.Where(x => x.Id == sessionId).ToListAsync();
            sw.Stop();
        }

        g = sw.ElapsedMilliseconds;

        // g = 328 ms

1 个答案:

答案 0 :(得分:4)

要在没有更多上下文的情况下确切地说是不可能的,但是总的来说,我认为您错误地认为异步应该更快,而实际上却相反。

异步是关于规模,而不是性能。它使您可以更有效地使用服务器资源,但是为此付出了代价,即使只是很小的代价。处理异步,线程切换等会涉及开销,所有这些操作实际上会使同一个操作慢于等效的同步操作。但是,同步没有任何机会在线程空闲时将其用于其他工作,因此您正在使用同步操作来限制潜在的服务器吞吐量。通常,异步处理是最好的选择。