我有一个控制器,它将OnActionExecuting重写为异步方法,如下所示:
protected override async void OnActionExecuting(ActionExecutingContext filterContext)
{
}
在该方法中,我调用了一些不可用的方法,例如
await db.Empresa.FindAsync(EmpresaID);
和
await UserManager.FindByIdAsync(User.Identity.GetUserId());
有了这个,我收到了错误:
ASP.NET控制器:异步模块或处理程序已完成,而异步操作仍处于挂起状态。
是否可以将OnActionExecuting
方法设置为异步?有办法解决这个问题吗?
否,它返回的是void
,而不是Task
或其他不可用的类型,因此调用代码将无法确定异步工作何时完成。
如果必须在OnActionExecuting
中使用异步方法(因为Entity Framework具有同步等效方法,所以看起来并不是这样(,那么只有次优的解决方法可用。
您需要阻塞当前线程,但需要注意不要由于ASP.NET的同步上下文而导致死锁。
一种选择是在线程池上运行异步代码:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var task = Task.Run(() => db.Empresa.FindAsync(EmpresaID));
var result = task.Result;
}
这实际上比简单地使用db.Empresa.Find(EmpresaID)
效率低,因为存在与Task.Run
相关联的开销。