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

Ric*_*mes 37 razor asp.net-core-mvc asp.net-core

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

@await Html.PartialAsync("_LoginPartial")
Run Code Online (Sandbox Code Playgroud)

@Html.Partial("_LoginPartial")
Run Code Online (Sandbox Code Playgroud)

有没有关于何时应该使用哪一个的文件?

Chr*_*att 34

这实际上是一个非常有趣的问题和场景.在某种程度上,异步是新的热点(尽管它并不是全新的).实体框架6使用异步方法和每个......单个......文件...点击...突然开始使用异步处理所有内容.我想我们在这里看到的有点相同.MVC 6支持异步渲染部分,所以OMG我们现在只需要使用异步.

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

特别是在渲染部分时,唯一不完全受CPU限制的部分是从文件系统中读取视图文件本身.虽然这在技术上足以使其符合异步的条件,但实际上需要多长时间才能阅读本质上可能小于50KB的文本文件.当线程被传递回池时,可能是时候请求它回来了,所以你实际上在那时使用资源效率更低.

多长时间,不要陷入"它可以做异步,所以我必须做异步"的陷阱.应根据其中是否存在实际价值来评估每种用途.Async有很多开销,如果你只是谈论几毫秒的等待时间,那么可能不值得花费额外的开销.

  • 实际上,`await`会产生当前线程,直到任务完成.这与等待状态无关. (4认同)
  • 不一定是"错误的".渲染部分需要命中文件系统.文件系统有一个队列,根据当时服务器上发生的其他情况,可能还有等待时间.任何涉及潜在必须等待的操作都有资格进行异步,因此在这方面,有一些像"PartialAsync"这样的东西是完全有效的.我的观点是,在大多数环境和使用async渲染局部的情况下会弄巧成拙,并且在使用异步时应始终评估*您的特定场景*.不要只使用异步,因为它就在那里. (2认同)
  • @ta.speot.is:确实如此。然而,这不是重点。如果您正在执行异步操作,那么是的,请使用异步,但问题是教程和此类内容往往没有区别,知识较少的开发人员会觉得您应该只使用异步,因为这就是教程的内容,书、视频等都做了。如果您只是渲染视图,那么异步执行可能不是正确的方法。 (2认同)
  • 是的。视图组件是异步的,如果你的部分正在做任何异步的事情,它本身应该是异步的。老实说,您可能会更频繁地使用 async。我只是想指出,在某些情况下,您实际上最好同步,因为大多数开发人员实际上并没有根据具体情况考虑它。 (2认同)

Fre*_*red 12

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

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

还有页面上的注释.

如果您的视图需要执行代码,则建议的模式是使用视图组件而不是局部视图.

所以你应该使用Partial并避免PartialAsync,如果你发现自己有一个PartialAsync你应该质疑自己是否做错了,也许你应该使用ViewComponent而不是将逻辑从视图移动到控制器.

  • 现在使用asp.net核心2.1,相同的文档提到_不建议使用同步等价物,因为有些情况下它们会死锁.**未来版本将不包含同步方法**._ (14认同)
  • 在 ASP.NET 3.1 中,使用“Partial”而不是“await .. PartialAsync”时会发出警告,因此现在不存在困境。 (5认同)

mik*_*kus 5

只是为了让那些在asp.net core时代访问的人保持线程最新。

目前,根据文档:

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

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

要了解为什么这是一个问题,您可以查看此 github 条目:

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

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

综上所述,没有真正的理由不使用 Async 版本。不使用同步是有原因的。即使视图中没有巨大的负载和奇特的逻辑,实际上很少有机会陷入死锁……但如果这样做,调试和修复将非常困难。

var result = htmlHelper.RenderPartialAsync(partialViewName, htmlHelper.ViewData.Model, viewData: null);
result.GetAwaiter().GetResult();
Run Code Online (Sandbox Code Playgroud)