【问题标题】:Making an async call in an MVC 5 action filter在 MVC 5 操作过滤器中进行异步调用
【发布时间】:2015-03-17 10:31:06
【问题描述】:

问题

我有一个 api GET 方法来检索站点配置。我正在使用httpClientGetAsync() 方法来执行此操作。

HttpResponseMessage response = await client.GetAsync("api/{0}/config", id);

由于我需要整个站点的此配置,因此我计划为此使用全局操作过滤器。

问题

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

我已经查看了多个关于此的 SO 问题 (Async action filter in MVC 4),但我没有找到令人满意的解决方案。

【问题讨论】:

  • 可以切换到 WebAPI 吗? :)
  • @YuvalItzchakov 我希望! :)
  • 谢谢@VsevolodGoloviznin 我已经阅读了这篇文章,虽然它提供了解释并没有提供合适的解决方案。
  • 好吧,因为它说没有办法以异步方式进行,所以你应该使用非异步方法

标签: asp.net-mvc async-await


【解决方案1】:

没有办法(可靠地)从 ASP.NET MVC 5 操作过滤器调用异步方法。这已经在 ASP.NET vNext 中得到修复,但是 AFAIK 没有计划在 MVC 5 中支持它。

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

【讨论】:

  • 谢谢。您是否建议不要在操作过滤器中执行类似 Task.Run(() => GetSomethingAsync(id)).Result; 的操作。如果可以,您能解释一下原因吗?
  • @ColinBacon:您可以使用a few hacks 来尝试强制“异步同步”,但每个都有缺点。 Task.Run 将干扰 ASP.NET 线程池启发式,对可伸缩性产生负面影响。此外,Task.Run 将显式运行 GetSomethingAsync 在当前 ASP.NET 请求上下文之外 - 这是否有效取决于 GetSomethingAsync 究竟试图做什么。所以简而言之,它可能有效(对性能的影响很小),也可能无效 - 取决于您的方法的实现。
  • 我可以确认对可扩展性的负面影响。我们有一个相当大的站点在 Azure 上运行,我正在做这件事:Task.Run(() => DoSomethingAsync).Wait() 在一个操作过滤器中。在重负载下,这会导致糟糕的性能。当线程耗尽时,请求被添加到请求队列中。 CPU 很低,因此不会添加任何实例,因为异步工作正在调用 3rd 方服务。我们最终得到了 +100 秒的响应时间。不要这样做:-)
猜你喜欢
  • 2014-10-04
  • 2012-09-11
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
  • 2019-06-19
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多