我正在研究 WCF Web 服务的性能改进。此 Web 服务调用可能需要很长时间(5 秒以上)才能响应的其他 Web 服务。在我们的服务负载很高的情况下,我们可能会遇到所有线程都被使用的情况,因为它们正在等待下游服务响应。这会导致整个系统备份等。
所以我正在研究使用 WCF 异步任务模式是否真的会有所帮助。我真正的问题是调用下游服务的线程在等待响应时到底发生了什么?该线程是否仍分配给调用,只是在后台工作池或其他地方?我需要能够证明迁移到异步任务实际上会降低使用的线程数,如果确实如此的话。
我正在研究 WCF Web 服务的性能改进。此 Web 服务调用可能需要很长时间(5 秒以上)才能响应的其他 Web 服务。在我们的服务负载很高的情况下,我们可能会遇到所有线程都被使用的情况,因为它们正在等待下游服务响应。这会导致整个系统备份等。
所以我正在研究使用 WCF 异步任务模式是否真的会有所帮助。我真正的问题是调用下游服务的线程在等待响应时到底发生了什么?该线程是否仍分配给调用,只是在后台工作池或其他地方?我需要能够证明迁移到异步任务实际上会降低使用的线程数,如果确实如此的话。
您在这里想要的是将您的长时间运行的线程返回到线程池并执行所谓的完成以让该线程获取响应......基本上您的目标应该是让一个线程处理对您的服务的传入请求,然后调用等待已久的外部服务,几乎立即返回线程池,以便对您的服务的其他请求可用。然后在通知第三方服务响应已准备好时,将分配它或线程池中的不同线程来获取响应并处理它。
Task 框架更多地用于并行化,而更少用于基于线程池的完成/拖尾模式。它产生一个线程来做一些工作,但除非你以相当高级的方式手动干预,否则所述线程不会在长时间运行的调用之间返回到池中。相反,您可以研究的是异步模式调用:Begin/End 语法。
http://msdn.microsoft.com/en-us/library/ms228963(v=vs.100).aspx
这些方法/完成将在等待响应时将线程释放到池中,这应该释放所述线程以处理更多服务调用。
如果您使用的是 .NET 4.5,则 async/await 关键字是此模式的漂亮包装,您可以使用它们来代替。
我假设您托管在 ASP.NET 上。在这种情况下,当一个方法正在执行一个请求时await
,请求线程将完全返回到线程池中,并且可以自由处理其他请求。
最简单的测试方法是限制服务器端的线程:
int workerThreads, ioThreads;
ThreadPool.GetMaxThreads(out workerThreads, out ioThreads);
ThreadPool.SetMaxThreads(Environment.ProcessorCount, ioThreads);
并在执行同时请求的客户端测试器中设置ServicePointManager.DefaultConnectionLimit
为。int.MaxValue
Environment.ProcessorCount + 1
我在这里有这个测试的 WebAPI 示例。将其转换为 WCF 示例应该不难。