async 在这种情况下是否提供性能改进? (.Net Core 2.1 Web API)

Does async provide performance improvements in this scenario? (.Net Core 2.1 Web API)

我有一个 .Net Core 2.1 Web API。我的许多控制器操作都不是异步的,我正在考虑让它们异步。但我想知道至少在简单的场景中它是否会有任何性能改进?以一个非常基本的动作为例:

// GET: api/People/5
[HttpGet("id")]
public Person GetPerson([FromRoute] int id)
{
    return _context.People.FirstOrDefault(p => p.Id == id);
}

如果我将其转换为:

// GET: api/People/5
[HttpGet("id")]
public async Task<Person> GetPerson([FromRoute] int id)
{
    return await _context.People.FirstOrDefaultAsync(p => p.Id == id);
}

当然,至少在这个非常基本的例子中,这两个动作会在同一时间段内执行?我的意思是,即使有两个同时调用非异步操作方法,IIS/Kestrel 也会承担创建它的第二个实例以允许两者同时执行的任务吗?我的意思是,这不像是因为一个客户端调用了这个 API 端点,现在所有其他客户端都必须等待它完成才能为它们提供服务,因为它不是异步的?

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

Asynchrony is essential for activities that are potentially blocking, such as web access. Access to a web resource sometimes is slow or delayed. If such an activity is blocked in a synchronous process, the entire application must wait. In an asynchronous process, the application can continue with other work that doesn't depend on the web resource until the potentially blocking task finishes.

通过 async/await 您可以释放您的应用程序以管理其他工作

异步与性能无关,它与可伸缩性有关。事实上,您实际上是在 牺牲 原始性能以获得更好的可伸缩性,因为异步至少有一定的开销,这将导致一切至少稍微降低性能,即使它只是一个纳秒级。

A​​sync 有一个目的:允许线程在空闲时返回到池中。而 sync 将保留线程,无论它是否处于等待状态。但是,不能保证线程会被释放,甚至 可以 被释放,因为异步方法通常需要做同步工作(即 CPU-bound),因为好吧,这需要主动使用线程。

当你被猛烈抨击时,你才能诚实地看到真正的好处。在您的 Web 服务变得线程匮乏的情况下 运行 所有同步,您可能能够使用异步推送更多请求。影响的程度不仅取决于服务器的冲击程度,还取决于所有组成操作的冲击程度。对于单个 FirstOrDefault 查询的示例,在大多数情况下,它可能会接近瞬时。但是,如果您的数据库实例受到一些 large/complex 查询的影响,或者只是因为查询过多而无法及时处理,那么突然之间,这个简单的过程可能会开始比正常情况下花费更长的时间。然后可能会开始备份队列中的请求。异步给你一些喘息的空间。

总而言之,使用异步的性能权衡通常非常小,在您需要它的时候,它可以成为救命稻草。你总是可以等待,分析,先看看是否有问题,然后返回并使事情异步,但事后返回并将非异步的事情重新调整为异步有点让人头疼。如果需要完成任何异步工作,从一开始就使用异步几乎总是更好 (I/O)。

此外,FWIW,虽然并非总是如此,特别是对于 EF Core,实际上没有 "sync" 访问权限。非异步方法只是阻塞异步版本。所以,真的没有什么好的借口不继续使用异步版本。