2012-08-09 99 views
0

我想建立一個多線程服務器,應該爲每個傳入連接產生新線程,但是對於我所有的努力,它只在感覺像它時纔會產生新線程,任何人都可以幫助我調試碼?我錯過了一些明顯的東西?C#多線程調試

while (true) 
{ 
    if (txtAddress.Text.Trim() == "Any" || txtAddress.Text.Trim() == "any") 
     ipEndP = new IPEndPoint(IPAddress.Any, 778); 
    else 
     ipEndP = new IPEndPoint(IPAddress.Parse(txtAddress.Text.Trim()), 778); 

     tcpL = new TcpListener(ipEndP); 
     tcpL.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 

     tcpL.Start(); 
     tempSock = tcpL.AcceptSocket(); 

//t = new Thread(ConnectionHandler); //When new client is connected, new thread  //is created to handle the connection 
//t.Priority = ThreadPriority.Highest; 
//t.Start(tempSock); 

ThreadPool.QueueUserWorkItem(ConnectionHandler, tempSock); 
} 

回答

4

退房MSDN文檔爲QueueUserWorkItem

隊列以供執行的方法。該方法在線程池線程變爲可用時執行。

在用戶工作項目隊列中放置一個線程並不保證它將立即開始執行。這實際上是一件好事。如果你有這麼多的連接,你需要數百或數千個線程,這很容易使你的服務器癱瘓(由於過度的上下文切換肯定會浪費很多)。

您的註釋掉的代碼應該爲每個連接啓動一個新的線程。這不行嗎?如果是這樣,那究竟是不是工作?請注意,爲每個連接創建一個新線程比使用線程池要昂貴得多。

UPDATE

根據你的話,該註釋掉的代碼也未能創造太多的線程,我想補充...

你正在創建的方式,如果出現這種情況線程太多。

我經常看到有人問他們爲什麼在一個過程中不能創建超過2000個線程。原因並不是Windows中固有的特定限制。相反,程序員沒有考慮到每個線程使用的地址空間量。

線程由內核模式(內核堆棧和對象管理)中的某些內存,用戶模式下的某些內存(線程環境塊,線程本地存儲等等)及其堆棧組成。 (或者如果您使用的是Itanium系統,則堆疊)。

通常,限制因素是堆棧大小。

http://blogs.msdn.com/b/oldnewthing/archive/2005/07/29/444912.aspx

+1

IMO你不使用線程池是不明智的。線程池在99%的時間內比手動線程執行得更好。 – Dan 2012-08-09 02:28:28

+0

另一個有用的參考是http://msdn.microsoft.com/en-us/library/0ka9477y.aspx – 2012-08-09 02:28:38

+0

這裏有一個平衡點,使用線程池可能適用於短暫連接。如果連接足夠長,那麼隨着時間的推移線程池將耗盡。國際海事組織(IMO)對每個套接字操作的讀寫都安排在線程池中會更好,這可以通過位於http://msdn.microsoft.com/en-us/library/system的SocketAsyncEventArgs示例輕鬆完成。 net.sockets.socketasynceventargs.aspx。表示連接的狀態可以很容易地維護而不需要專用線程。 – 2012-08-09 02:33:59