为什么在使用 MediatR 和 async/await 时我的 ASP.NET 核心控制器性能变慢?
Why is my ASP.NET Core controller performance slow when using MediatR and async/await?
我正在使用 MiniProfiler 试图找出为什么我的 ASP.NET Core 5.0 Web 应用程序的性能比预期的要慢。
我已将问题缩小到控制器中的 MediatR 调用(执行 1201 毫秒),但这很奇怪,因为当我深入研究 MediatR 执行的处理程序时,处理程序的整个主体运行时间更少超过 50 毫秒(包括 Entity Framework 核心数据库调用 MS SQL 服务器)。
这是我的相关代码:
控制器
public async Task<IActionResult> Index(GetAnnouncementsRequest query)
{
using (MiniProfiler.Current.Step("[AnnouncementsController] Index"))
{
IEnumerable<GetAnnouncementsDto> model;
using (MiniProfiler.Current.Step("[AnnouncementsController] Index: MediatR"))
{
model = await _mediator.Send(query)
.ConfigureAwait(false);
}
return View(model);
}
}
处理程序
public async Task<IEnumerable<GetAnnouncementsDto>> Handle(GetAnnouncementsRequest request, CancellationToken cancellationToken)
{
using (MiniProfiler.Current.Step("[GetAnnouncementsRequest] Handle"))
{
List<Announcement> announcements;
IReadOnlyCollection<GetAnnouncementsDto> announcementsDto;
using (MiniProfiler.Current.Step("[GetAnnouncementsRequest] Handle: GetAllActiveAsync"))
{
announcements = await _announcementRepository.GetAllActiveAsync()
.ConfigureAwait(false);
}
using (MiniProfiler.Current.Step("[GetAnnouncementsRequest] Handle: Mapper"))
{
announcementsDto = _mapper.Map<List<Announcement>, List<GetAnnouncementsDto>>(announcements)
.OrderByDescending(announcement => announcement.EditedDate)
.ThenByDescending(announcement => announcement.PostedDate)
.ToList()
.AsReadOnly();
}
return announcementsDto;
}
}
存储库
public async Task<List<Announcement>> GetAllActiveAsync()
{
var announcements = await GetAll()
.Where(announcement => announcement.IsActive)
.ToListAsync()
.ConfigureAwait(false);
return announcements;
}
这是探查器返回的数据:
我对嵌套 async
/await
的使用有问题吗?我是否错误地使用了中介者模式?还是我没有正确使用 MiniProfiler?我不明白为什么 MediatR 调用这么慢。
作为参考,我在本地服务器上使用传统的 WISA 堆栈(Windows/IIS/SQL Server/ASP.NET Core)。
事实证明,我注入了一项服务,该服务在我已设置为 Scoped 的请求中间执行了一些繁忙的身份验证工作。我将其更改为 Singleton,它完全解决了这个问题。现在我的页面加载时间为 10-20 毫秒。
我正在使用 MiniProfiler 试图找出为什么我的 ASP.NET Core 5.0 Web 应用程序的性能比预期的要慢。
我已将问题缩小到控制器中的 MediatR 调用(执行 1201 毫秒),但这很奇怪,因为当我深入研究 MediatR 执行的处理程序时,处理程序的整个主体运行时间更少超过 50 毫秒(包括 Entity Framework 核心数据库调用 MS SQL 服务器)。
这是我的相关代码:
控制器
public async Task<IActionResult> Index(GetAnnouncementsRequest query)
{
using (MiniProfiler.Current.Step("[AnnouncementsController] Index"))
{
IEnumerable<GetAnnouncementsDto> model;
using (MiniProfiler.Current.Step("[AnnouncementsController] Index: MediatR"))
{
model = await _mediator.Send(query)
.ConfigureAwait(false);
}
return View(model);
}
}
处理程序
public async Task<IEnumerable<GetAnnouncementsDto>> Handle(GetAnnouncementsRequest request, CancellationToken cancellationToken)
{
using (MiniProfiler.Current.Step("[GetAnnouncementsRequest] Handle"))
{
List<Announcement> announcements;
IReadOnlyCollection<GetAnnouncementsDto> announcementsDto;
using (MiniProfiler.Current.Step("[GetAnnouncementsRequest] Handle: GetAllActiveAsync"))
{
announcements = await _announcementRepository.GetAllActiveAsync()
.ConfigureAwait(false);
}
using (MiniProfiler.Current.Step("[GetAnnouncementsRequest] Handle: Mapper"))
{
announcementsDto = _mapper.Map<List<Announcement>, List<GetAnnouncementsDto>>(announcements)
.OrderByDescending(announcement => announcement.EditedDate)
.ThenByDescending(announcement => announcement.PostedDate)
.ToList()
.AsReadOnly();
}
return announcementsDto;
}
}
存储库
public async Task<List<Announcement>> GetAllActiveAsync()
{
var announcements = await GetAll()
.Where(announcement => announcement.IsActive)
.ToListAsync()
.ConfigureAwait(false);
return announcements;
}
这是探查器返回的数据:
我对嵌套 async
/await
的使用有问题吗?我是否错误地使用了中介者模式?还是我没有正确使用 MiniProfiler?我不明白为什么 MediatR 调用这么慢。
作为参考,我在本地服务器上使用传统的 WISA 堆栈(Windows/IIS/SQL Server/ASP.NET Core)。
事实证明,我注入了一项服务,该服务在我已设置为 Scoped 的请求中间执行了一些繁忙的身份验证工作。我将其更改为 Singleton,它完全解决了这个问题。现在我的页面加载时间为 10-20 毫秒。