我正在读一本书,我发现当我们创建或替换资源时,put动词使用相同的URI,而帖子创建新资源的标识符。
事实上,
答案 0 :(得分:9)
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中的asynchronous programming,因此为ASP.NET Web API服务编写异步方法非常容易。只需将返回类型设置为Task(如果同步版本返回void)或Task,将T替换为同步方法的返回类型。然后从该方法中执行非阻塞的IO绑定异步操作。
将方法标记为async允许您等待异步操作,编译器将其余方法转换为在另一个线程上执行的延续或回调,通常从线程池中获取。
阅读有关此Build Async Services with ASP.NET Web API and Entity Framework 6
的完整文章