.NET 性能最佳做法:避免阻塞调用

ASP.NET Core 应用应设计为可同时处理许多请求。异步 API 允许较小线程池处理数千个并发请求,无需等待阻塞调用。线程可以处理另一个请求,而不是等待长时间运行的同步任务完成。

ASP.NET Core 应用中的一个常见性能问题是阻塞可以异步进行的调用。许多同步阻塞调用都会导致线程池饥饿和响应时间降低。.

禁止行为:

  • 通过调用 Task.Wait 或 Task<TResult>.Result 阻止异步执行。

  • 获取常见代码路径中的锁。当构建为并行运行代码时,ASP.NET Core 应用的性能最高。

  • 调用 Task.Run 并立即等待。ASP.NET Core 已经在普通线程池线程上运行应用代码,因此调用 Task.Run 只会导致不必要的额外线程池计划。即使计划的代码会阻止某个线程,Task.Run 也不会阻止该线程。

建议做法:

  • 使热代码路径成为异步。

  • 如果有异步 API 可用,则异步调用数据访问、I/O 和长时间运行的操作 API。 不要使用 来异步同步 API。

  • 使控制器/Razor Page 操作成为异步。为了获益于 async/await 模式,整个调用堆栈都是异步的。

探查器(例如 PerfView)可用于查找频繁添加到线程池中的线程。 Microsoft-Windows-DotNETRuntime/ThreadPoolWorkerThread/Start 事件指示添加到线程池的线程。