【问题标题】:When using Asynchronous OnActionExecuting: An asynchronous module or handler completed while an asynchronous operation was still pending使用异步 OnActionExecuting 时:异步模块或处理程序已完成,而异步操作仍处于挂起状态
【发布时间】:2020-04-07 18:37:38
【问题描述】:

我有一个控制器,它的 OnActionExecuting 被重写为异步方法,这样:

protected override async void OnActionExecuting(ActionExecutingContext filterContext)
{
}

在该方法中,我调用了一些可等待的方法,例如 await db.Empresa.FindAsync(EmpresaID);await UserManager.FindByIdAsync(User.Identity.GetUserId());

这样,我收到错误:ASP.NET Controller: An asynchronous module or handler completed while an asynchronous operation was still pending

是否可以将OnActionExecuting 方法设为异步?有没有办法解决这个问题?

詹姆

【问题讨论】:

  • 旁注:ASP.NET Core 确实支持异步操作过滤器。

标签: c# asynchronous async-await asp.net-mvc-5.2


【解决方案1】:

不,它返回 void 而不是 Task 或其他可等待类型,因此调用代码将无法确定异步工作何时完成。

如果您必须在 OnActionExecuting 中使用异步方法(并且您似乎没有这样做,因为 Entity Framework 具有同步等效项),则只有次优的解决方法可用。

您将需要阻塞当前线程,但您需要注意不要因为 ASP.NET 的同步上下文而导致死锁。

一种选择是在线程池上运行异步代码:

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var task = Task.Run(async () => db.Empresa.FindAsync(EmpresaID));
    var result = task.Result;
}

这实际上比简单地使用db.Empresa.Find(EmpresaID) 效率低,因为有与Task.Run 相关的开销。

【讨论】:

  • 我终于替换了 EF 中同步对应的所有异步调用。
猜你喜欢
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多