WCF 是不是使用 ThreadPool 为 PerCall 服务启动新实例?
Posted
技术标签:
【中文标题】WCF 是不是使用 ThreadPool 为 PerCall 服务启动新实例?【英文标题】:Does WCF use the ThreadPool to bring up new instances for a PerCall service?WCF 是否使用 ThreadPool 为 PerCall 服务启动新实例? 【发布时间】:2011-02-19 14:32:22 【问题描述】:对于限制设置为高(例如,最大 200 个并发调用)的 PerCall WCF 服务,WCF 是否会启动一个新实例并在线程池线程上调用请求?
如果有,那么这对允许的并发调用总数有影响吗?
我问是因为我似乎没有达到我在服务限制配置中设置的最大并发调用数,而是该数字的一小部分 - 在 100 MaxConcurrentCalls 设置上最多 50 个,在 200 个设置上最多 160 个MaxConcurrentCalls 设置。
谢谢,
【问题讨论】:
据我所知,WCF 对其请求使用单独的线程池。它没有利用“正常”的 .NET 线程池。 【参考方案1】:WCF 似乎使用来自 CLR 线程池的托管 I/O 线程来处理请求,但需要注意的是使用自己的线程调度程序。
来自Wenlong Dong's Blog - Why Are WCF Responses Slow and SetMinThreads Does Not Work?
首先,WCF 使用托管 I/O 线程来处理请求。 CLR ThreadPool 保持一定数量的空闲 I/O 线程不被销毁。当需要更多 I/O 线程时,它们由 ThreadPool 创建,这有点昂贵。
来自Wenlong Dong's Blog : WCF Request Throttling and Server Scalability
在 .NET 3.0 和 3.5 中,您会观察到 IIS 托管的 WCF 服务的特殊行为。每当有请求进来时,系统会使用两个线程来处理请求:一个线程是 CLR ThreadPool 线程,它是来自 ASP.NET 的工作线程。 另一个线程是由 WCF IOThreadScheduler 管理的 I/O 线程(实际上是由 ThreadPool.UnsafeQueueNativeOverlapped 创建的)。
有很多设置会影响 WCF 吞吐量。因为 WCF 使用托管的 ThreadPool,所以 ThreadPool 的 MinIOThreads 和 MaxIOThreads 设置会影响结果。从 ThreadPool 中取出所有空闲 I/O 线程(或工作线程,如果您正在使用这些线程)之后,ThreadPool 将延迟一段时间,然后再启动一个新线程以服务排队的请求。通过增加 MinIOThreads,您可以防止这种延迟。如果您达到 MaxIOThread 限制,那肯定会限制您将看到的并发请求数;但是,在您的 50/100 测试中似乎并非如此,因为您的下一个测试设法让 160 个并发请求运行。如果我没记错的话,我相信您使用的托管环境(IIS、WAS、self)可以决定一些 ThreadPool 设置。此外,如果您阅读第二个链接中的博客文章,您将看到当 WCF 在其单独的 I/O 线程上处理请求时,IIS 工作线程是如何被阻塞的。所以在这种情况下,工作线程设置和 IIS 设置会对 WCF 并发产生影响。您如何托管此服务?
您的标题提到了 PerCall InstanceContextMode,这将使 ConcurrencyMode 无关紧要。但是,对于 PerCall,您需要了解 MaxConcurrentInstances 设置以及 MaxConcurrentCalls。根据您的绑定,您可能还需要关注 MaxConcurrentSessions 属性。您使用什么绑定来托管此服务?
不管上述所有情况,令人困惑的是在您的 50/100 测试之后的 160/200 测试。
【讨论】:
以上是关于WCF 是不是使用 ThreadPool 为 PerCall 服务启动新实例?的主要内容,如果未能解决你的问题,请参考以下文章
为啥使用 ThreadPool 检查代理比不使用 ThreadPool 需要更多时间?