2014-04-09 3 views
0

안녕하세요,이 스레드를 실행할 때 높은 CPU 사용량 (15-16 %)이 발생했습니다. "ssStop"이 true (작동)로 설정되어 있지 않으면 루핑을 유지해야하는 스레드입니다. 그러나, 실행중인 동안 작업 관리자를 열고 프로그램이 컴퓨터 처리 능력의 15 %를 사용하고 있음을 알았습니다. 일단 스레드가 종료되면 다시 1-2 %로 떨어집니다. 나는이 문제를 찾고 발견 EventWaitHandle를 사용하는 경우에도 온라인 여전히 사람이 내가 잘못 여기서 뭘하는지 알 수 있습니까? 당신은 연결을 위해 혼잡 폴링 CPU 사이클을 구울스레드 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

, 당신은'수면 (1)를 삽입 할 수 있습니다'어딘가에 루프를 실행하여 다른 스레드를 실행할 수있게합니다. 그러나 코드에 다른 문제가 있습니다. 작동하는 코드이므로 codereview.stackexchange.com에 게시하여 추가 피드백을 얻을 수 있도록하십시오. WaitEventHandle을 사용하더라도 다른 스레드에서 수행 할 작업이 없으면 CPU 사용량에 영향을 미치지 않는다고 생각합니다. –

+0

시계 틱을 측정 할 수있는 계기를 추가하십시오. 그러면 CPU 사용량을 줄이는 데 도움이됩니다. 시스템 또는 함수 호출의 시계를 측정하십시오. 그러나 틱을 측정하는 것은 약간의 오버 헤드를 유발할 것이므로 생산을 위해하지 마십시오. 측정은 항상 추측보다 낫다. –

답변

1

를이 높은 남아있다. 대부분의 시간을 고려 Pending false를 반환되어, 루프는 다음과 같이 주위 회전된다

myEventHandle 다음 WaitOne에서 10ms의 지연이 효과적으로 스로틀 실행하지만, 내 생각 엔 이벤트가 설정되어 있는지 될 것를 설정되지 않은 경우 지금
while (!ssStop) 
{ 
    tcpReceiver = new TcpClient(); 
    myEventHandle.WaitOne(10, false); 
} 

따라서 WaitOne은 즉시 true을 반환합니다.

AcceptTcpClient은 연결 대기를 차단하므로 연결을 폴링 할 필요는 없습니다. 당신은 약간의 주위에 당신의 코드를 변경 한 경우 그래서 예상대로 작동합니다 : 당신이 각 루프 동안 20 밀리 초 이상 스레드를 포기 감당할 수있는

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