Web Api控制器和线程池

10
当IIS收到HTTP请求时,它将该请求移交给一个应用程序池中的被一个或多个工作进程服务的请求应用程序。如果需要,工作进程将从共享线程池生成线程以服务于HTTP请求。
(i) 在Web API控制器的上下文中,当接收到此请求时,控制器是否会被实例化并分配给生成的线程?
(ii) 当同一API控制器有多个HTTP请求时,每个生成的线程是否都有控制器的多个实例?
(iii) 在一个不是线程安全的资源(dbContext)在类级别上声明并在构造函数中实例化,然后在类方法中使用的场景中。提交和管理事务是否存在问题?
总之,控制器实例与线程是一一对应的吗?(我知道在ASP.NET中,多个线程实际上可以为单个HTTP请求提供服务)。
2个回答

4
当收到请求时,ControllerFactory或DependencyResolver将创建一个控制器实例。
基本上,主线程创建一个控制器实例,然后同一个实例在多个线程之间共享,直到请求完成。
是的,共享成员或静态成员不是线程安全的。但是,在操作方法内部的局部变量是线程安全的。

因此,在操作方法中实例化dbcontext并在操作方法的范围内重复使用它们,以及不同存储库的多个实例都是有意义的。我已经尝试过这个方法,并且它可以正常工作 :) 。但我担心是否存在任何代码异味... - Oladipo Olasemo

0
回答您的问题:
(i). 是的。
(ii). 不是。通常控制器是单例且不线程安全的。您可以创建多个线程来处理多个请求,但它们会调用同一控制器实例(或服务)。
(iii). 是的。确保数据完整性检查或线程安全性方面是您的责任。如果您不这样做,则可能会遇到各种问题,如脏读、脏写、线程安全性等各种线程安全性问题。

您可以将控制器视为服务,因此只需通过创建新实例将传入请求委托给新子服务或控制器,例如为每个请求创建新任务处理程序,但仍需要考虑共享资源(如数据库)的线程安全性。


1
你确定你对(ii)的答案正确吗? 在这个页面上 https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection它说道: “控制器是每个请求创建的。” 但也许我误解了你的意思。 - schmendrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接