jstuardo
jstuardo

Reputation: 4373

overriding OnActionExecuting as async

I have a Controller which has OnActionExecuting overridden as async method, this way:

protected override async void OnActionExecuting(ActionExecutingContext filterContext)
{
}

Inside that method I am calling some awaitable methods, such as

await db.Empresa.FindAsync(EmpresaID);

and

await UserManager.FindByIdAsync(User.Identity.GetUserId());

With that, I am receiving the error:

ASP.NET Controller: An asynchronous module or handler completed while an asynchronous operation was still pending.

Is it possible to make OnActionExecuting method as async? Is there a way to solve this?

Upvotes: 1

Views: 847

Answers (1)

Johnathan Barclay
Johnathan Barclay

Reputation: 20354

No, it returns void not Task or another awaitable type, so the calling code won't be able to determine when the asynchronous work has completed.

If you must use an asynchronous method within OnActionExecuting (and it doesn't appear as though you do, because Entity Framework has synchronous equivalents) there are only sub-optimal workarounds available.

You will need to block the current thread, but you need to be careful that you don't cause a deadlock due to ASP.NET's synchronisation context.

One option is to run the asynchronous code on the thread pool:

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

This would actually be less efficient than simply using db.Empresa.Find(EmpresaID), as there is overhead associated with Task.Run.

Upvotes: 2

Related Questions