【问题标题】:Asynchronous action for strongly-typed partial view in _Layout_Layout 中强类型分部视图的异步操作
【发布时间】:2012-10-24 20:29:33
【问题描述】:

所以,这里是纲要...

我的 MVC 4 应用程序有一个主布局页面,其中包含一些动态信息,需要强类型化到特定域实体才能获取该信息。为了让我的文件更整洁,我将输入的字段提取到部分视图中。

为了获取我需要的实体并将其映射到局部视图模型,我有一个 LayoutController,其操作返回 Task<PartialViewResult>。此操作使用服务层向 Web API 项目发出 async 调用,awaiting 实体。它将该实体按摩到视图模型中,然后返回PartialView("_LayoutPartial", viewModel).

在 _Layout 页面中,部分通过以下方式调用:

@{Html.RenderAction("LayoutInfo", "Layout", new { /*entity primary key*/ });}

我已经单步执行了代码,它确实返回了正确的实体,但是在返回部分视图任务后,我得到了大家最喜欢的服务器错误页面,并出现以下错误:

HttpServerUtility.Execute blocked while waiting for an asynchronous operation to complete.

我进行了一些谷歌搜索和 SO 搜索,但不知道这实际上意味着什么。我的想法正确吗?

【问题讨论】:

    标签: asp.net .net asp.net-mvc-4 partial-views async-await


    【解决方案1】:

    该错误消息意味着您正在尝试从同步方法中调用(并等待!)异步方法。在您的特定情况下,同步方法是 HtmlHelper.RenderAction,异步方法是您的任务返回操作方法。出现错误的原因是写异步Task-returning方法的点大概是为了避免阻塞一个线程,但是RenderAction要等到Task完成后才能返回,所以RenderAction在等待操作完成的时候就阻塞了。

    一种选择是使 RenderAction 调用的方法同步而不是异步,请记住,这将继续阻塞原始线程。另一种选择是从原始操作方法中异步填充布局数据,然后通过 ViewData 将其传递给布局页面。

    【讨论】:

    • 感谢您的建议和解释!我确实通过使操作同步然后使用_service.GetEntity(...).Result 尝试了您的第一个建议,但它会永远挂起,这完全是另一个我不知道如何处理的问题。我会试试你的其他选择,看看我能不能让它工作。如果可以的话,我会为你 +1 以获得好的解释!
    • 好吧,我试过了,遇到了类似的问题...Task.Wait() 永远挂起,页面根本不加载,Task.ContinueWith() 跳到返回视图之前ViewBag 被填满,所以有一个空引用异常。有趣的是……在第二种情况下,在空引用异常命中后,我在 ContinueWith 中的断点终于被命中,任务得到了正确的响应。这很奇怪。
    猜你喜欢
    • 1970-01-01
    • 2012-09-30
    • 2013-04-23
    • 2010-10-12
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 1970-01-01
    相关资源
    最近更新 更多