繁体   English   中英

我应该在ASP.NET Web API的控制器中使用异步方法

[英]Should I use asynchronous methods in controllers of ASP.NET Web API

我正在读一本书,我发现当我们创建或替换资源时,put动词使用相同的URI,而帖子创建新资源的标识符。

事实上,

  1. 这是否意味着控制器(apicontroller)中的post动作总是会创建一个新的资源实例?
  2. 它会创建一个新的独立线程吗?
  3. 我不需要担心在我的控制器中将我的方法声明为异步,因为它会为任何http请求创建一个新线程?
  4. 对于put动作,我是否需要将我的方法声明为异步,以避免在使用Web资源时发生锁定?

1)是否意味着控制器(apicontroller)中的post动作总是会创建一个新的资源实例?

2)它会创建一个新的独立线程吗?

是。 但请记住,方法上的动作动词与线程的处理无关。 在任何API调用中,都会创建一个新线程,或者请求将使用来自线程池的现有线程。

3)我不需要担心在我的控制器中将我的方法声明为异步,因为它会为任何http请求创建一个新线程?

简短的回答是,如果你关心缩放,你应该总是编写异步方法。 阅读详细故事了解更多细节。

4)对于PUT操作,我是否需要将我的方法声明为异步以避免在使用Web资源时发生锁定?

正如我之前所说,你的行动,PUT或POST无关紧要。 如果您进行阻塞I / O操作(如访问数据库),最好使用异步方法。

很长的故事

基于ASP.NET Web API的Web服务(专门支持REST)使用.NET线程池来响应请求。 但是,仅仅因为服务本质上是多线程的,并不会在同时发出大量请求时使它们扩展。 线程被汇集而不是动态创建的原因是因为它们在内存和CPU利用率方面都是非常昂贵的资源。 例如,除了寄存器集上下文和线程属性之外,每个线程消耗大约1 MB的堆栈空间。

因此,一旦线程完成其工作,它将保持活动大约一分钟,在另一个机会中,另一个请求将到达并且等待线程可用于为其提供服务。 这意味着如果在执行服务请求期间,另一个请求到达,则将从线程池中检索另一个线程以服务第二个请求。 如果没有可用的线程,将从头开始创建一个线程,这可能需要500毫秒,在此期间请求将被阻止。 如果您有大量的操作请求需要很长时间才能完成,则会创建越来越多的线程,消耗额外的内存并对服务的性能产生负面影响。

故事的寓意是: 不要在服务操作中阻止执行线程。

但是,这正是执行IO绑定任务时发生的情况,例如从数据库检索或保存数据或调用下游服务时。

如果对数据库的调用需要几秒钟或更长时间,并且另一个调用进来(即使是另一种方法),则需要从线程池中获取另一个线程。

由于支持.NET 4.5和C#5中的异步编程 ,因此为ASP.NET Web API服务编写异步方法非常容易。 只需将返回类型设置为Task(如果同步版本返回void)或Task,将T替换为同步方法的返回类型。 然后从该方法中,执行非阻塞IO绑定异步操作。

将方法标记为异步允许您等待异步操作,编译器将其余方法转换为在另一个线程上执行的延续或回调,通常从线程池中获取。

阅读有关使用ASP.NET Web API和Entity Framework 6构建异步服务的完整文章

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM