2014-02-21 38 views
0

我使用这里的答案(https://stackoverflow.com/a/2759898)渲染视图作为字符串。渲染视图作为字符串(异步)

我是新来的异步等待的事情。只需要知道下面的代码是否会真正释放资源,直到渲染视图?假设我的视图需要5秒才能呈现。

public async Task<string> RenderViewToString(string viewName, object model) 
{ 
    ViewData.Model = model; 
    using (var sw = new StringWriter()) 
    { 
    return await Task.Run(() => 
    { 
     var razor = new RazorViewEngine(); 
     var viewResult = razor.FindView(ControllerContext, viewName, null, false); 
     var viewContext = new ViewContext(ControllerContext, viewResult.View, 
     ViewData, TempData, sw); 
     viewResult.View.Render(viewContext, sw); 
     viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View); 
     return sw.GetStringBuilder().ToString(); 
    }); 
    } 
} 

P.S.不要问我为什么我的观点需要时间来呈现。虽然这不是一个推荐的做法,但是对于这个特定的实例,我必须在视图中调用几个Web服务并创建json输出。

回答

1

如果你的看法被调用Web服务你没有关注的MVC模式 - 需要“渲染”你的观点不应该包括它需要使Web服务调用的时间的时间 - 你应该在所有这些控制器并将所有Web服务结果/数据的最终化模型传递到视图 - 然后不必担心视图或其他资源...

此外,当结果是Json - 你应该只有一个返回JsonResult的控制器。

+0

我知道这是一个不好的做法,但我迫切需要这样做,作为我们当前项目中的临时黑客。我们将尽快解决它。 – user3219798

2

号这是什么东西做的是它的实际获得从ASP.NET线程池的另一个线程运行的Task.Run()身体。在Task.Run()的执行过程中,请求线程返回到线程池。一旦Task.Run()完成,它返回该线程并获得一个完成请求。所有这些代码正在做的事情是增加工作......它实际上使情况变得更糟。

如果视图调用Web服务,看看你是否可以异步调用Web服务。这就是异步/等待会提高效率的地方。

+0

实际上,当Task.Run执行时,线程返回到池中(这就是我想要的)。我不确定,如果在正常情况下,线索将专用于VIEW 5秒(如果查看需要5秒钟完成)? – user3219798

+0

是的,请求线程返回到池中,但它从同一个池中取出另一个线程来执行'Task.Run()'中的工作,并且它将挂起到完成,然后将其返回到池中,最后得到一个线程来完成请求。与仅仅挂在整个请求的请求线程中相比,你没有什么收获。事实上,由于交换线程的开销,情况更糟。它使应用程序的可扩展性和性能降低。 –

+0

您可以请建议如何释放所有的线程,并在ViewResult完成时得到通知? – user3219798

0

虽然您将要使用的环境不清楚,但我会推测您正在尝试获取呈现的视图,以便它可以使用Ajax返回,并且仅允许您更新页面的某个区域。

嗯,这不是MVC的正确方法。正如罗布所说,你应该尝试使用JsonResult。如果你认为你想从Web服务返回的数据被传递到视图,那么最好试着获得一个JsonResult并使用Ajax调用这个方法。另外,如果你想以某种方式用这个渲染视图作为字符串替换你的页面或元素的内容,更好的方法是简单地创建一些局部视图并在视图中将它们作为@ Html.Action( “查看”, “控制器”)。这样你甚至可以获得html。您也可以使用Ajax调用它并将其推送到要显示视图的容器元素。