Web Api 控制器和线程池

Posted

技术标签:

【中文标题】Web Api 控制器和线程池【英文标题】:Web Api Controller and Thread Pool 【发布时间】:2016-06-10 12:36:07 【问题描述】:

当 IIS 接收到 HTTP 请求时,它会将请求移交给应用程序池中的请求应用程序,该应用程序池由一个或多个工作进程提供服务。工作进程将从共享线程池(如果需要)生成一个线程来服务 http 请求。

(i) 在 web api 控制器的上下文中,当收到此请求时,控制器是否被实例化并分配给衍生线程?

(ii) 当对同一个 api 控制器有多个 http 请求时,每个生成的线程是否会有尽可能多的控制器实例?

(iii) 在类级别声明非线程安全资源 (dbContext) 并在构造函数中实例化然后在类方法中使用的场景中。提交和管理事务会不会有问题?

本质上,每个线程是否存在一对一的控制器实例匹配? (我知道使用 asp.net 多个线程实际上可以为单个 http 请求提供服务)。

【问题讨论】:

【参考方案1】:

(i) 在 web api 控制器的上下文中,当这个请求被 收到的,是控制器实例化并分配给产生的 线? (ii) 当对同一个api控制器有多个http请求时, 每个生成的线程会有多少个控制器实例?

当收到请求时,ControllerFactory 或 DependencyResolver 创建一个控制器实例。

基本上,主线程创建一个控制器实例,然后同一个实例在多个线程之间共享,直到请求完成。

(iii) 在资源不是线程安全的情况下 (dbContext) 在类级别声明并在 构造函数然后在类方法中使用。会不会有问题 提交和管理事务?

是的,共享成员或静态不是线程安全的。但是,动作方法中的局部变量是线程安全的。

【讨论】:

因此,在操作方法中实例化 dbcontext 并在操作方法范围内使用不同存储库的多个实例重用它们是有意义的。我已经尝试过了,它可以工作:)。但我担心任何代码气味......【参考方案2】:

逐点回答您的问题: (一世)。是的 (二)。不。通常控制器是单例的,不是线程安全的。您创建多个线程来处理多个请求,但它们调用相同的控制器实例(或服务) (iii)。是的。您有责任照顾数据完整性检查或线程安全问题。如果您不这样做,那么您可能会面临各种问题,例如脏读、脏乘、线程安全……各种线程安全问题。

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

【讨论】:

您确定您对 (ii) 的回答吗?在此页面docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/… 上它声明:“控制器是根据请求创建的。”但也许我误解了你

以上是关于Web Api 控制器和线程池的主要内容,如果未能解决你的问题,请参考以下文章

Web — 线程池的创建方式

为啥我的异步 ASP.NET Web API 控制器阻塞了主线程?

2,Executor线程池

多线程--Executor线程池框架

线程的控制和线程池

锁定 Web API 控制器方法