2010-01-22 50 views
2

我有一个定期执行HTTP帖子(从SQL检索数据)的应用程序。每30秒钟最多可产生50个线程并同时运行HTTP帖子。如果帖子失败,只要间隔设置为,它就会等待2x。这将发生两次。例如,30年代,60年代,然后是120年代。线程HTTP发布应用程序

我正在使用正常的Thread.Start()来实现这个过程,但是我发现在实时服务器上,它完全湮没了CPU。

我的问题如下:

  • 是否有更好的类中使用线程性能?
  • 有没有办法在.NET中限制线程应用CPU使用率?

感谢,

凯尔

+2

你的重试逻辑是有缺陷的,它应该小于间隔,否则它只会排队到无穷大:) – leppie 2010-01-22 05:47:06

+0

需要这种方式,我很害怕。它只会在当前批次完全排序后才运行下一批,因此它不会无限期地运行。 – 2010-01-22 05:50:59

回答

1

您不应该使用线程来运行多个I/O流。由于这些线程大多阻塞在I/O上,因此可以更高效地使用非阻塞或异步I/O。与一台服务器只有一个线程交谈,而不是与一台服务器交谈。

由于您使用的是HttpWebRequest,因此您需要查看HttpWebRequest.BeginGetResponseHttpWebRequest.BeginGetRequestStream

+0

我同意...我正在通过.BeginInvoke(...)思考异步操作,也许是一个委托。 – IAbstract 2010-01-22 17:28:21

+0

谢谢,我一定会在可以的时候看看这个。 – 2010-02-18 07:35:40

0

我很抱歉,我没有多线程HTTP职位的经验。

话虽如此,您用于HTTP post的类是什么?
我想,它应该有方法以异步的方式做HTTP POST。

而且,如果这不起作用,您可以使用ThreadPool而不是创建自己的线程。

+0

我无法使用异步帖子,因为我需要返回。它使用普通的旧HttpWebRequest来完成文章。在这种情况下ThreadPool会给我带来什么好处? – 2010-01-22 05:52:06

+0

你*可以*在你的请求中使用异步。您可以在.NET中的任何代理上执行BeginInvoke(),这使您有机会在HttpWebRequest上使用异步。为什么你应该使用线程池,请参阅我的答案。 http://stackoverflow.com/questions/2115299/threaded-http-post-application/2115395#2115395 – Cheeso 2010-01-22 06:17:09

0

是否真的有必要让50个线程同时运行?

试着限制产生的线程数量,比如只有10个线程,然后按批量运行。

1

一般来说,使用ThreadPool

在每个.NET进程中都有一个线程池,一个线程池准备好为您工作。你应该使用它。

对于原因,看Thread vs ThreadPool,或The .NET ThreadPool

简短的说就是:它的效率高得多,而且它更亲切的你的CPU,比目前需求启动线程的方法。

.NET还有一个evry易于使用的机制,用于将工作发送到线程池中的线程:ThreadPool.QueueUserWorkItem

我不知道.NET线程池是如何在内部进行管理的,但我知道工程师比我更聪明,他们已经完成了分析工作来弄清楚它应该做什么,应该有多少线程,它应该如何表现为不会淹没CPU。是的,它的设计特别是,以避免你所描述的问题。如果线程池足够用于ASPNET工作进程,那么对于我的应用程序来说可能就足够了。

也是你的。

0

我想知道你还有什么可以运行的clobbers CPU性能(如低效率的监测循环),或者它是否是因为你已经用完内存的页面文件抖动问题。如果您的工人班有很多本地数据,您可以快速吸收内存。

我已经做了类似的使用HttpWebRequest,并已能够有约100个同时在飞行中的连接,但在这一点上我已经超出网络带宽和内存,尽管50个连接运行良好。我创建了自己的线程,而不是使用ThreadPool,因为我使用回调函数,所以我可以轻松跟踪线程状态,甚至在需要时中止线程。它也简化了从失败的连接重新启动 - 我只是把线程放回到待处理线程的队列中。

ThreadPool有助于防止启动太多的线程,但我认为线程创建开销与网络连接响应延迟相比微不足道(至少在我的经验中)。