【问题标题】:Calling Async Methods in Action Filters in MVC 5在 MVC 5 的动作过滤器中调用异步方法
【发布时间】:2014-10-04 10:39:21
【问题描述】:

我正在编写一个动作过滤器(继承自 ActionFilterAttribute),它使用 HttpClientOnResultExecuted 方法中将数据发布到外部服务器。 HttpClient 有方法PostAsync,它返回一个等待的Task<HttpResponseMessage>

public override void OnResultExecuted(ResultExecutedContext filterContext)
{
    using (var client = new HttpClient())
    {
        var task = client.PostAsync(GetUri(), GetContent());
        var result = task.Result; // blocking
    }
}

Async action filter in MVC 4 接受的答案说在 MVC 4 中是不可能的。

这在 MVC 5 中是否仍然如此,如果是这样,在不阻塞线程的情况下调用此异步方法的最佳方法是什么?

【问题讨论】:

  • 不,因为从技术上讲,它不再是覆盖(方法定义本质上会有所不同)。它只是你添加的一个新方法,框架永远不会调用它。
  • @ChrisPratt 正如我所说,测试它..我在发表之前的评论之前做过。
  • 该方法仍将运行同步,除非它可以返回 Task。添加async 不是魔杖。
  • 哇,好吧,这里的理解有些崩溃。你用 async 装饰一个方法并且它运行的事实并不意味着它是异步运行的。我完全肯定您可以运行该代码,但它绝对不会异步运行。也许您实际上并不了解异步是什么意思?这意味着该方法将在等待操作完成时放弃其线程以供其他进程使用。然后,一旦操作完成,它就会请求线程返回并继续。同步方法一直挂在线程上。
  • 你们都是对的,但由此产生的行为很可能是非常错误的。过滤器将运行,但管道将在异步过滤器完成之前继续。例如,假设您想包含外部调用的结果(或者例如检查它并返回一些其他 HTTP 响应代码):这将失败,因为当异步调用返回时结果已经在进行中(这就是异步void 确实,“一劳永逸”)

标签: c# asp.net-mvc asp.net-mvc-5 async-await


【解决方案1】:

是的,它仍然是真的。 Web API 2 支持异步操作过滤器,但 MVC 5 仍然不支持。不久前,我个人对此感到沮丧。目前,您需要在操作过滤器中将异步方法作为同步运行,或者在每个需要它的操作中重复操作过滤器中的异步代码,然后可以 异步运行。

【讨论】:

  • 您能否详细说明“在每个需要它的操作中重复异步代码”的意思?
  • 从字面上看,重复代码。无论您的操作过滤器里面有什么,将该代码按字面意思放在需要它的操作中,您将能够异步运行。显然,这并不理想,所以最好的方法可能是同步运行它,但如果你绝对必须异步运行,没有其他方法。
  • 呃。这确实不理想。这是一个如此缺乏的功能,真是太可惜了。
  • 我同意,而且添加起来似乎也很容易。希望 vNext 会支持它,但无论如何,vNext 完全不同。
  • vNext 支持(已经)。新的 MVC/WebAPI 控制器都支持异步操作过滤器和异步子操作(vNext 中的“视图组件”)。当前 ASP.NET 上的 MVC 过于依赖于 ASP.NET 核心(以同步方式),所以我不希望在 vNext 之前解决这个问题。
【解决方案2】:

有些人在这里“向后移植”它

https://github.com/jdaigle/Hydrogen.Extensions.Mvc5

我没有尝试过,也不推荐它,但如果您正在过渡到 .NET Core,它可能值得考虑。幸运的是,我设法从我的扩展中删除了所有异步代码 - 这一次。

【讨论】:

    猜你喜欢
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2012-09-11
    • 2018-11-10
    • 2014-08-03
    • 2014-07-14
    相关资源
    最近更新 更多