2014-04-09 125 views
0

嗨我運行這個線程時CPU佔用率很高(15-16%),它是一個線程,應該保持循環,除非「ssStop」設置爲true(哪個工作)但是,在運行時,我打開任務管理器,發現程序使用了15%的計算機處理能力,一旦線程退出,它將降低到1-2%。使用的EventWaitHandle,我發現尋找這個問題即使在網上它仍然這麼高,沒有人知道我在做什麼錯在這裏?:線程c中的CPU使用率高#

public void Receive() 
{ 
    try 
    {    
     bool firstTimeRun = true; 
     TcpListener ssTcpListener = new TcpListener(IPAddress.Any, 1500); 
     TcpClient tcpReceiver; 
     ssTcpListener.Start(); 
     while (!ssStop) 
     { 
      //Start listening for connection. 
      //Accept any incoming connection requests on port 1500. 
      tcpReceiver = new TcpClient(); 
      if (ssTcpListener.Pending()) 
      { 
       tcpReceiver = ssTcpListener.AcceptTcpClient(); 
      } 
      if (tcpReceiver.Connected) 
      { 
       //looped for first time; receives whole image. 
       if (firstTimeRun) 
       { 
        //TCP connected. Receive images from contact 
        NetworkStream receivedNs = new NetworkStream(tcpReceiver.Client); 
        Bitmap image = new Bitmap(receivedNs); 
        receivedImage = image; 
        pboScrnShare.Image = image; 
        receivedNs.Flush(); 
        firstTimeRun = false;        
       } 
       //second time or higher looped; receives difference and overlays it. 
       else if (!firstTimeRun) 
       { 
        NetworkStream receivedNs = new NetworkStream(tcpReceiver.Client); 

        //Put image into picturebox. 
        receivedImage2 = new Bitmap(receivedNs); 
        receivedImage2.MakeTransparent(Color.Black); 
        Bitmap overlayedImage = new Bitmap(receivedImage.Width, receivedImage.Height); 

        using (Graphics gr = Graphics.FromImage(overlayedImage)) 
        { 
         gr.DrawImage(receivedImage, new Point(0, 0)); 
         gr.DrawImage(receivedImage2, new Point(0, 0)); 
        } 


        try 
        { 
         pboScrnShare.Image = overlayedImage; 
        } 
        catch (Exception ex) 
        { 
         MessageBox.Show(ex.Message, "pbo second run"); 
        } 
        receivedImage2.Dispose(); 
        if (this.InvokeRequired) { this.Invoke(new MethodInvoker(delegate() { receivedImage = overlayedImage; })); } else { receivedImage = overlayedImage; } 
        receivedNs.Flush(); 
       } 
       tcpReceiver.Close(); 
      } 
      myEventWaitHandle.WaitOne(10, true); 
     } 
     ssTcpListener.Stop(); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.ToString(), "Invited ReceiveSS()", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
} 
+3

如果你能負擔得起的每個循環中放棄對線程20毫秒或更多,你可以插入一個'睡眠(1)'某處你的循環允許其他線程執行。但是,您的代碼還存在其他問題。由於它是工作代碼,因此可以考慮將其發佈到codereview.stackexchange.com,以便獲得一些額外的反饋。即使你使用WaitEventHandle,我認爲它不會對你的CPU使用率產生任何影響,除非在其他線程中有某些事情要做。 –

+0

添加一些儀器來測量時鐘滴答。這將有助於縮小CPU使用率。測量系統或函數調用兩側的時鐘滴答聲。但請注意,測量刻度還會帶來一些開銷,所以不要做生產。測量總是比猜測好.... –

回答

1

您正在燃燒的CPU週期忙輪詢的連接。考慮到大部分的時間Pending是返回false,你的循環轉圈這樣的:

while (!ssStop) 
{ 
    tcpReceiver = new TcpClient(); 
    myEventHandle.WaitOne(10, false); 
} 

現在,如果myEventHandle沒有設置那麼WaitOne 10ms的延遲將切實油門執行,但我的猜測是,該事件被設置所以WaitOne立即返回true

由於AcceptTcpClient將阻止等待連接,所以不需要輪詢連接。所以,如果你身邊有點改變了你的代碼,它應該按預期工作:

while (!ssStop) 
{ 
    TcpClient tcpReceiver = ssTcpListener.AcceptTcpClient(); // this blocks 
    ... 
}