Task <t>是否实际上降低了使用的线程数?</t>

时间:2013-07-01 17:25:26

标签: c# .net wcf asynchronous task

我正在研究WCF Web服务的性能改进。此Web服务调用其他可能需要很长时间才能响应的Web服务(5秒以上)。由于我们的服务负载很高,我们可能会遇到使用所有线程的情况,因为它们正在等待下游服务响应。这导致整个系统备份等。

所以我正在研究如果使用WCF异步任务模式实际上会有帮助。我真正的问题是调用下游服务的线程究竟发生了什么,它正在等待响应?该线程是否仍然分配给调用,只是在后台工作池或其他什么?我需要能够证明,移动到异步任务实际上会减少使用的线程数,如果是的话。

2 个答案:

答案 0 :(得分:3)

你想要的是将长时间运行的线程返回到线程池并执行所谓的完成以使该线程获取响应...基本上你的目标应该是让一个线程处理传入的请求对您的服务,然后呼叫长期等待的外部服务,几乎立即返回到线程池,以便可用于您的服务的其他请求。然后在收到第三方服务响应准备的通知后,将分配来自线程池的或不同的线程来获取响应并进行处理。

Task框架更多用于并行化,而不是基于线程池的完成/拖尾模式。它产生一个线程来完成一些工作,但除非你以相当高级的方式手动干预,否则所述线程将不会在长时间运行的调用之间返回池。你可以看到的是异步模式调用:开始/结束语法。

http://msdn.microsoft.com/en-us/library/ms228963(v=vs.100).aspx

这些方法/完成将在等待响应时将线程释放到池中,这应该释放所述线程以处理更多服务的调用。

如果您使用的是.NET 4.5,那么async / await关键字对于此模式来说是一个非常好的包装,您可以使用它们。

答案 1 :(得分:1)

我假设你是在ASP.NET上托管的。在这种情况下,当方法执行await时,请求线程将完全返回到线程池,并可以自由处理其他请求。

最简单的测试方法是限制服务器端的线程:

int workerThreads, ioThreads;
ThreadPool.GetMaxThreads(out workerThreads, out ioThreads);
ThreadPool.SetMaxThreads(Environment.ProcessorCount, ioThreads);

并在执行ServicePointManager.DefaultConnectionLimit个并发请求的客户端测试人员中将int.MaxValue设置为Environment.ProcessorCount + 1

我有一个关于此测试的here的WebAPI示例。将它转换为WCF示例应该不难。