线程c中的CPU使用率高#
问题描述:
嗨我运行这个线程时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);
}
}
答
您正在燃烧的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
...
}
如果你能负担得起的每个循环中放弃对线程20毫秒或更多,你可以插入一个'睡眠(1)'某处你的循环允许其他线程执行。但是,您的代码还存在其他问题。由于它是工作代码,因此可以考虑将其发布到codereview.stackexchange.com,以便获得一些额外的反馈。即使你使用WaitEventHandle,我认为它不会对你的CPU使用率产生任何影响,除非在其他线程中有某些事情要做。 –
添加一些仪器来测量时钟滴答。这将有助于缩小CPU使用率。测量系统或函数调用两侧的时钟滴答声。但请注意,测量刻度还会带来一些开销,所以不要做生产。测量总是比猜测好.... –