【问题标题】:asynchronous call deadlock in MVC applicationMVC 应用程序中的异步调用死锁
【发布时间】:2015-12-19 11:11:24
【问题描述】:

我们希望在所有页面的底部显示来自后端服务的版本详细信息。

3 个后端服务是异步 webapi(2.2) 调用,我们需要让这 3 个异步调用将日期聚合到模型中,然后将其传递给视图。

如果我作为(非子)控制器操作的一部分执行此操作,代码将起作用并显示数据。

但是,尝试在每个页面的底部显示此数据(子操作)会产生几种不同的异步死锁类型条件。

子操作和调用 _layout.cshtml

    //ControllerAction
    [ChildActionOnly]
    public ActionResult VersionInfo()
    {
        var version = _versionInfoViewModelMapper.Map().Result;
        return View(version);...
    }

//Layout.cshtml
    @if(Request.IsAuthenticated)
    {
        Html.RenderAction("VersionInfo", "Utils");
    }

这会导致似乎是死锁,因为请求没有结束,

使用 ActionFilter

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var viewBag = filterContext.Controller.ViewBag;
        if (filterContext.RequestContext.HttpContext.Request.IsAuthenticated)
        {
            //viewBag.VersionInfo = Task.Run(() => _versionInfoViewModelMapper.Map()).Result;
            viewBag.VersionInfo = _versionInfoViewModelMapper.Map().Result;
        }
    }

使用上述过滤器将数据传递给 ViewBag,然后使用该过滤器,会产生相同的无休止调用。

如果我不在异步调用中使用 .Result,我会收到错误

HttpServerUtility.Execute 在等待异步时阻塞 操作完成。

有没有办法解决这个问题?可能通过使用 Global.asax Application_PostAuthenticateRequest 或类似事件?

【问题讨论】:

  • 子操作似乎不支持异步,请参阅this questionthis other question。请求in codeplex 被关闭为“在 MVC 6 中作为视图组件的一部分添加”
  • Task.Run 包裹不起作用吗?
  • 是的,这就是我最初尝试异步子操作后遇到此问题的原因。
  • @Kędrzu 我不记得它给出了哪些错误状态,但也失败了,你可以看到我在 actionfilter 尝试中将其注释掉了。

标签: c# asp.net-mvc asp.net-web-api asp.net-mvc-5.2


【解决方案1】:

问题出在这里:

_versionInfoViewModelMapper.Map().Result;

调用Task.Result,以及Task.Wait(),以防有SynchronizationContext 集合(在ASP 环境中是这样)可能会导致严重的死锁。

改为使用您的方法的异步版本:

public async Task<ActionResult> VersionInfo()
{
    var version = await _versionInfoViewModelMapper.Map();
    return View(version);...
}

有关此问题的更多信息,请参阅this Stephen Cleary blog post

【讨论】:

  • 你不能有异步子任务,我从这个开始并且得到了导致我调查其他方法的错误。按照链接关闭此stackoverflow.com/questions/29519253/…
  • 是的,我刚刚调查了这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-22
  • 2016-12-02
  • 2014-09-12
相关资源
最近更新 更多