2010-01-22 113 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有助於防止啓動太多的線程,但我認爲線程創建開銷與網絡連接響應延遲相比微不足道(至少在我的經驗中)。