Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run async method in overridden void

I'm currently building an ASP.NET MVC application. I'm trying to add items to the ViewBag property for all pages in my site. To achieve this, I've created a base controller that all my site controllers inherit from.

To add to the ViewBag, I've overridden the OnActionExecuting method: protected override void OnActionExecuting(ActionExecutingContext filterContext)

I know that the OnActionExecuting methods for MVC5 are not async, which is why I'm running into this issue. I need to be able to call some form of the following code to retrieve the newest items and put them into the ViewBag:

IList<PlaceListItemViewModel> places = await GetLatestPlaces(3);
ViewBag.FooterLatestPlaces = places;

Using the GetLatestPlaces(3).Result just causes a deadlock, so this is not an option.

Could anybody give me an option on how to achieve this. It doesn't have to be overriding the OnActionExecuting method either, if there is another way to add items to the ViewBag for every page (other than calling the code from every single action in every controller), I'm open to using that method.

Unfortunately I can't the GetLatestPlaces method to be non-async, as it's using the MongoDB 2.0 driver, which is async all the way.

like image 314
Juzzbott Avatar asked May 27 '15 02:05

Juzzbott


1 Answers

There are two general methods to achieve what you wanted:

  1. Use ConfigureAwait(false) in your async library. In your case you should do it inside GetLatestPlaces() method.
  2. Call your async method in a different thread in order to not block the current context. So your code will look like this:

    IList<PlaceListItemViewModel> places = Task.Run(async () =>  await GetLatestPlaces(3)).Result;
    

For more info see Stephen Cleary's excellent blog post.

like image 165
Arin Ghazarian Avatar answered Nov 09 '22 19:11

Arin Ghazarian