在MVC 5动作过滤器中进行异步调用

Col*_*con 14 asp.net-mvc async-await

问题

我有一个api GET方法来检索站点配置.我正在使用httpClientGetAsync()方法来做到这一点.

HttpResponseMessage response = await client.GetAsync("api/{0}/config", id);
Run Code Online (Sandbox Code Playgroud)

由于我需要跨站点进行此配置,因此我计划使用全局操作过滤器.

如何在MVC动作过滤器中调用异步方法?或者这个问题有更好的解决方案吗?

我已经看过多个SO问题(MVC 4中的异步动作过滤器),但我没有找到满意的解决方案.

Ste*_*ary 19

无法(可靠地)从ASP.NET MVC 5动作过滤器调用异步方法.这已在ASP.NET vNext中修复,但AFAIK没有计划在MVC 5中支持这一点.

如果您绝对必须在动作过滤器中执行此操作,则必须使用同步调用(例如,WebClient而不是HttpClient).

  • 我可以确认对可扩展性的负面影响.我们在Azure上运行了一个相当大的站点,我正在做这个事情:`Task.Run(()=> DoSomethingAsync).Wait()`在一个动作过滤器中.在重负荷下,这导致了糟糕的表现.当线程耗尽时,请求被添加到请求队列中.CPU很低,因此异步工作调用第三方服务时不会添加任何实例.最终我们的响应时间为+100秒.不要这样做 :-) (8认同)
  • @ColinBacon:你可以使用[几个黑客](http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx)强制"同步异步",但每个人都有缺点.`Task.Run`将干扰ASP.NET线程池启发式,对可伸缩性产生负面影响.此外,`Task.Run`将在当前的ASP.NET请求上下文之外显式运行`GetSomethingAsync`* - 这是否有效取决于`GetSomethingAsync`究竟要做什么.简而言之,它可能会起作用(性能损失很小),或者可能不起作用 - 取决于您的方法的实现. (3认同)
  • 谢谢。您是否建议不要在操作过滤器中执行类似“Task.Run(() => GetSomethingAsync(id)).Result;”的操作。如果是,你能解释一下原因吗? (2认同)