2012-06-14 51 views
0

我有一個C#服務,這是相當大的,它可以作爲一個服務器應用程序與少數(約5)客戶端同時進行通信。每個客戶端都是一個線程,主要將數據放入Access數據庫並從中取出數據。該服務在啓動時運行良好,但在幾天後,CPU就會瘋狂(提高99%),服務開始減速很多。我不知道是什麼造成了這個...有無論如何看到在一個服務,需要CPU,什麼功能線程?不知道如何更好地描述它,但只是提出問題,如果你需要更多的信息來幫助! :)看看服務中需要什麼CPU編輯:(多線程...)

/尼克

編輯:我如何創建線程和他們做了什麼......(我使用過程Expolorer後,我發現我哈得很多運行)

private void ListenForClients() 
{ 
      this.tcpListener.Start(); 

      while (true) 
      { 
       TcpClient client = this.tcpListener.AcceptTcpClient(); 

       Connection c = new Connection(this.parent); 
       Thread clientThread = new Thread(new ParameterizedThreadStart(c.HandleClientComm)); 

       threadCollection.Add(clientThread); 
       clientThread.Start(client); 
      } 
} 

public void HandleClientComm(object client) 
    { 
     try 
     { 

      TcpClient server = (TcpClient)client; 

      NetworkStream ns = server.GetStream(); 
      byte[] data = new byte[1024]; 
      string input, stringData; 

      while (true) 
      { 
       try 
       { 
        data = new byte[1024]; 
        if (ns.DataAvailable && ns.CanRead) 
        { 
         int recv = ns.Read(data, 0, data.Length); 
         if (recv > 0) 
         { 
          if ((byte)data[recv - 1] == (byte)255) 
          { 
           int cnt = -1; 
           for (int i = 0; i < recv; i++) 
           { 
            if (data[i] == (byte)254) 
             cnt = i; 
           } 

           int nr = recv - cnt - 2; 
           byte[] tmp = new byte[nr]; 

           for (int i = 0; i < nr; i++) 
           { 
            tmp[i] = data[cnt + i + 1]; 
           } 
           string crc = Encoding.UTF8.GetString(tmp); 
           stringData = Encoding.UTF8.GetString(data, 0, cnt); 

           MsgStruct msgs = new MsgStruct(stringData); 
           msgs.setCrc(crc); 
           Thread.Sleep(200); 

           addTodo(msgs); 
          } 
         } 


        } 
        if (parent.cStructHandler.gotMsg(this.ID)) 
        { 
         MsgStruct tmpCs = parent.cStructHandler.getNextMsg(this.ID); 

         if (tmpCs.getMsg().Length != 0 && ns.CanWrite) 
         { 
          byte[] ba = Encoding.UTF8.GetBytes(tmpCs.getMsg()); 

          if (tmpCs.getCrc() == "") 
          { 
           ulong tmp = CRC.calc_crc(ba, ba.Length); 
           tmpCs.setCrc(tmp.ToString("X")); 
          } 

          if (tmpCs.canSendByTimeout()) 
          { 
           string crcStr = "?" + tmpCs.getCrc() + "?"; 
           byte[] bb = Encoding.UTF8.GetBytes(crcStr); 
           crcStr = Encoding.UTF8.GetString(bb); 
           byte[] fullMsg = new byte[ba.Length + bb.Length]; 
           bb[0] = 254; 
           bb[bb.Length - 1] = 255; 

           ba.CopyTo(fullMsg, 0); 
           bb.CopyTo(fullMsg, ba.Length); 
           string s = System.Text.UTF8Encoding.ASCII.GetString(fullMsg); 

           ns.Write(fullMsg, 0, fullMsg.Length); 
           Thread.Sleep(200); 
           if (!tmpCs.isAckNeeded()) 
            parent.cStructHandler.removeNextMsg(this.ID); 
          } 
         } 
        } 

        Thread.Sleep(100); 
       } 
       catch (Exception e) 
       { 
        break; 
       } 

      } 
      ns.Close(); 
      server.Close(); 

     } 
     catch (Exception e) 
     { 
     } 
    } 
+1

您需要分析器。 –

+1

附上一個調試器並看看? –

+0

你什麼時候離開了(true)以防萬一沒有例外發生?請看我更新的答案。 –

回答

1

我添加的代碼建議你使用某種跟蹤的,只是爲了看看你的器件的應用是這樣做的:

這裏是點網log 4 net Tutorial

一個簡單的日誌框架nd:正如你所說這是一個長時間運行的服務器進程,我推薦使用 滾動日誌(即如果日誌文件具有一定數量的行,則使用新文件 )。 log4net RollingFileAppender派上用場。

您應該使用跟蹤標準情況的高電平(即同時 一切工作就好了),並且能夠切換到較低水平 更多的輸出,當有需要時(即當你serverprocess去橫行)。

,當然,你可以有通過jetbrains tool

一看也強烈建議那些展鵬工具:ANTS performance profilerDot Net Reflector

編輯

幾乎忘了提:一我最喜歡的工具:Process Explorer

EDIT2

在做工作的情況下,你需要休息,離開時真的,我覺得

+0

我使用Process Explorer進行了檢查,並且有很多線程在運行,它們會在函數完成運行時停止運行(客戶端斷開連接)嗎?我在我的第一篇文章的某些代碼中編輯過,供您查看! – Nick3

+0

哦......我相信它永遠不會真的離開while(true)部分,因此永遠不會結束線程,從而擁有越來越多的線程。 –

0

嘗試查看打開的句柄(文件)。 我敢打賭,你忘了不具有天然資源(忘了using建設)

0

主要問題在你的代碼是,你是無限生成的線程,並可能不會釋放他們都在threadCollection。

也許ThreadPool.QueueUserWorkItem「火&忘記」在你的情況下更好?