Vnu*_*uuk 202 c# asp.net asynchronous async-await asp.net-mvc-4
我有一些担心在ASP.NET MVC中使用异步操作.当它提高了我的应用程序的性能,并且在做它不是?
Ste*_*ary 218
您可能会发现关于该主题的MSDN文章很有帮助 ; 我在该文章中占用了大量空间,描述了何时应该async在ASP.NET上使用,而不仅仅是如何async在ASP.NET 上使用.
我有一些担心在ASP.NET MVC中使用异步操作.当它提高我的应用程序的性能,以及何时 - 不是.
首先,要了解async/ await是关于释放线程的全部内容.在GUI应用程序上,它主要是释放GUI线程,以便用户体验更好.在服务器应用程序(包括ASP.NET MVC)上,它主要是释放请求线程,以便服务器可以扩展.
特别是,它不会:
await.await只有"产生"到ASP.NET线程池,而不是浏览器.第一个问题是 - 在ASP.NET MVC中到处使用异步操作是否合适?
我说在你做I/O的任何地方都可以使用它.但这可能不一定有益(见下文).
但是,将它用于CPU绑定方法是不好的.有时开发人员认为他们可以async通过调用Task.Run控制器来获得好处,这是一个可怕的想法.因为该代码最终通过占用另一个线程来释放请求线程,所以根本没有任何好处(实际上,它们会受到额外线程切换的惩罚)!
当我想查询数据库(通过EF/NHibernate /其他ORM)时,我应该使用async/await关键字吗?
您可以使用任何可用的方法.现在大多数主要球员都支持async,但也有一些不支持.如果您的ORM不支持async,那么不要尝试将其包装Task.Run或类似的东西(见上文).
请注意,我说"你可以使用".如果您正在谈论具有单个数据库后端的ASP.NET MVC,那么您(几乎可以肯定)不会从中获得任何可伸缩性的好处async.这是因为IIS可以处理比单个SQL Server实例(或其他经典RDBMS)更多的并发请求.但是,如果您的后端更现代 - 一个SQL服务器集群,Azure SQL,NoSQL等 - 并且您的后端可以扩展,并且您的可伸缩性瓶颈是IIS,那么您可以从中获得可伸缩性的好处async.
第三个问题 - 我可以使用等待关键字在一个单一操作方法中异步查询数据库的次数?
尽你所愿.但是,请注意,许多ORM具有每操作一个操作规则.特别是,EF只允许每个DbContext进行一次操作; 无论操作是同步还是异步,都是如此.
另外,请记住后端的可扩展性.如果您正在使用SQL Server的单个实例,并且您的IIS已经能够使SQLServer保持满负荷运行,那么SQLServer的压力加倍或增加三倍根本不会对您有所帮助.
Tha*_*rif 100
当操作必须执行多个独立的长时间运行操作时,异步操作方法很有用.
AsyncController类的典型用法是长时间运行的Web服务调用.
我的数据库调用应该是异步的吗
IIS线程池通常可以处理比数据库服务器更多的同时阻塞请求.如果数据库是瓶颈,异步调用将不会加速数据库响应.如果没有限制机制,通过使用异步调用有效地将更多工作分配给不堪重负的数据库服务器,只会将更多的负担转移到数据库.如果您的数据库是瓶颈,异步调用将不是神奇的子弹.
源于@PanagiotisKanavos评论:
而且,异步并不意味着并行.异步执行使得有价值的线程池线程免于阻塞外部资源,因为没有复杂性或性能成本.这意味着相同的IIS计算机可以处理更多并发请求,而不是它将运行得更快.
您还应该考虑阻塞调用以CPU密集型spinwait开始.在压力期间,阻止呼叫将导致延迟和应用程序池回收不断升级.异步调用只是避免这种情况
Yuv*_*kov 20
在ASP.NET MVC中使用异步操作是否很好?
像编程一样,它取决于.沿着某条路走下去时总会有一个权衡.
async-await在你知道你将收到并发请求服务的地方闪耀,你希望能够很好地扩展.如何async-await帮助扩展?事实上,当您同步调用异步IO调用(例如网络调用或命中数据库)时,将阻止负责执行的当前线程等待请求完成.使用时async-await,启用框架为您创建状态机,确保在IO调用完成后,您的方法从中断处继续执行.
需要注意的是,这个状态机有一个微妙的开销.使方法异步并不会使它执行得更快,这是一个重要的理解因素和许多人的误解.
在使用时需要考虑的另一件事async-await是它一直是异步的,这意味着你会看到异步穿透你的整个调用堆栈,从顶部到底部.这意味着如果您想要公开同步API,您通常会发现自己复制了一定数量的代码,因为异步和同步不能很好地混合.
当我想查询数据库(通过EF/NHibernate /其他ORM)时,我应该使用async/await关键字吗?
如果您选择沿着使用异步IO调用的路径前进,那么是的,async-await将是一个不错的选择,因为越来越多的现代数据库提供程序公开了实现TAP(任务异步模式)的异步方法.
有多少次我可以使用await关键字在一个单一动作方法中异步查询数据库?
只要您遵循数据库提供商声明的规则,就可以随心所欲.您可以进行异步调用的数量没有限制.如果您的查询彼此独立且可以同时进行,则可以为每个查询创建一个新任务,并await Task.WhenAll等待两者都完成.
我的5美分:
async/await当且仅当你做一个IO操作,如数据库或外部服务web服务.PS第1点有例外情况,但您需要对异步内部有很好的理解.
另外一个优点是,如果需要,您可以并行执行少量IO调用:
Task task1 = FooAsync(); // launch it, but don't wait for result
Task task2 = BarAsync(); // launch bar; now both foo and bar are running
await Task.WhenAll(task1, task2); // this is better in regard to exception handling
// use task1.Result, task2.Result
Run Code Online (Sandbox Code Playgroud)
async当动作对数据库或某些网络绑定调用执行某些操作时,操作会有所帮助,其中处理请求的线程在从您刚刚调用的数据库或网络绑定调用中获得应答之前将被停止.你最好使用等待它们,它将真正提高你的应用程序的响应能力(因为在等待数据库或任何其他类似的操作时,较少的ASP输入\输出线程将被停止).在我的所有应用程序中,每当多次调用DB非常必要时,我总是将它们包装在可用的方法中并使用await关键字调用它.
| 归档时间: |
|
| 查看次数: |
99666 次 |
| 最近记录: |