何时在MVC 6中的视图中使用@await Html.PartialAsync



我在Scott Hanselman的一个博客上注意到,在使用.Net 5(MVC 6)时,他在视图中使用了以下代码:

@await Html.PartialAsync("_LoginPartial")

与。

@Html.Partial("_LoginPartial")

关于什么时候应该使用哪一个,还有什么文件吗?

这实际上是一个非常有趣的问题和场景。在某种程度上,异步是一种新的热点(尽管它并不是那么新)。实体框架6与异步方法和每个。。。仅有一个的块属于文档突然开始对所有内容使用异步。我想我们在这里看到了一些相同的东西。MVC 6支持异步,比如渲染部分,所以OMG我们现在都有使用异步。

Async有一个非常特殊的用途。它允许在当前任务处于等待状态时将活动线程返回到池中以字段其他任务。其中的关键部分是"等待状态"。某些任务与async完全不兼容。像复杂的财务分析这样的CPU绑定工作从不允许线程进入等待状态,因此即使您将其设置为异步,一切都可以有效地作为同步运行。另一方面,涉及网络延迟(从web API请求资源、查询数据库等)或I/O绑定(读取/写入文件等)的事情有时会有线程在继续处理之前等待其他进程完成的时间段。

具体来看,渲染部分,唯一不完全受CPU限制的部分是从文件系统读取视图文件本身。虽然从技术上讲,足以使其符合异步条件,但读取一个可能最大小于50KB的文本文件实际需要多长时间。当线程返回到池时,可能是时候请求它了,所以在这一点上,您实际上使用资源的效率更低。

长话短说,不要陷入"它可以异步完成,所以我必须异步完成"的陷阱。每一次使用都应该根据它是否真的有价值来评估。异步有很多开销,如果你只谈论几毫秒的等待时间,那么它可能不值得所有额外的开销。

根据部分视图的ASP.NET MVC文档。https://docs.asp.net/en/latest/mvc/views/partial.html

PartialAsync方法可用于包含异步代码的部分视图(尽管通常不鼓励视图中的代码):

还有页面上的注释。

如果视图需要执行代码,建议使用视图组件而不是局部视图。

因此,您应该使用Partial,避免使用PartialAsync,如果您发现自己有PartialAsync,您应该质疑自己是否做错了什么,也许您应该使用ViewComponent,或者将逻辑从视图移动到控制器。

只是为了让那些在asp.net核心时代访问的人了解最新消息。

目前,根据文件:

Partial和RenderPartial分别是PartialAsync和RenderPartyAsync的同步等价物。不建议使用同步等价物,因为在某些情况下它们会死锁同步方法的目标是在将来的版本中删除

完整内容:ASP.NET Core 中的部分视图

要了解为什么会出现这种问题,您可以查看github条目:

https://github.com/aspnet/Mvc/issues/7083

但长话短说,Partial的同步版本看起来只是用GetResult调用async one,这在某些情况下会导致死锁。

总之,没有真正的理由不使用异步版本。不使用同步的原因是有的。即使在视图中没有巨大的负载和花哨的逻辑,也几乎没有机会真正陷入死锁。。。。但是,如果您这样做,调试和修复将非常困难。

var result = htmlHelper.RenderPartialAsync(partialViewName, htmlHelper.ViewData.Model, viewData: null);
result.GetAwaiter().GetResult();

关于"wait Html.PartialAsync"-此链接可能会帮助您-http://aspnetwebstack.codeplex.com/workitem/601(也关注评论)(关于之前到底是什么问题)。

我正在开发一个基于MVC 6构建的面向公众的网站,"等待Html.PartialAsync"比"Html.Parial"更快,尤其是当视图包含大量组件时。

从Html.PartialAsync中取出"wait"显然不起作用,Html.PrtialAsync会吐出类型名称(即"System.Threading.Tasks.Task`1[Microsoft.AspNet.Mvc.Frendering.HtmlString]")而不是实际视图。

招魂。

选项1:

您的子部分视图在Razor标记中有一些异步await代码——它可能会死锁,因为MS代码只调用GetAwaiter().GetResult(),这就是导致死锁的原因。

使用PartialAsync

选项2:

您的局部视图没有任何await,但您的模型生成代码有(例如Html.Partial("MyView.cshtml", new MyModel { PropertyX = await XyzXyz() }),那么它可能也会死锁。

使用PartialAsync

选项3:

您的partial完全不使用async/await。

可以使用Html.Partial(同步)