在重写的void中运行async方法

Juz*_*ott 7 c# asp.net asp.net-mvc async-await asp.net-mvc-5

我目前正在构建一个ASP.NET MVC应用程序.我正在尝试将项目添加到我的网站中所有页面的ViewBag属性中.为此,我创建了一个基本控制器,我的所有站点控制器都继承了该控制器.

要添加到ViewBag,我已经重写了OnActionExecuting方法: protected override void OnActionExecuting(ActionExecutingContext filterContext)

我知道MVC5的OnActionExecuting方法不是异步的,这就是我遇到这个问题的原因.我需要能够调用以下代码的某种形式来检索最新的项目并将它们放入ViewBag中:

IList<PlaceListItemViewModel> places = await GetLatestPlaces(3);
ViewBag.FooterLatestPlaces = places;
Run Code Online (Sandbox Code Playgroud)

使用GetLatestPlaces(3).Resultjust会造成死锁,所以这不是一个选择.

任何人都可以给我一个如何实现这一目标的选择.它也不必重写OnActionExecuting方法,如果有另一种方法将项添加到每个页面的ViewBag(除了从每个控制器中的每个动作调用代码),我愿意使用该方法.

不幸的是,我不能将GetLatestPlaces方法设置为非异步,因为它使用MongoDB 2.0驱动程序,它始终是异步的.

Ari*_*ian 13

有两种通用的方法可以达到你想要的效果:

  1. ConfigureAwait(false)在您的async图书馆中使用.在你的情况下,你应该在GetLatestPlaces()方法内做.
  2. async在不同的线程中调用您的方法,以便不阻止当前上下文.所以你的代码看起来像这样:

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

有关更多信息,请参阅Stephen Cleary的优秀博客文章.

  • 在ASP.NET应用程序中调用`Task.Run`会因为不必要的上下文切换而损害性能. (2认同)