使用C#写了一个串口通信界面,使用的是队列的方式来处理数据,即将接收数据、数据解析分开,首先使用C#自带的serialPort_DataReceived函数接收数据,然后将接收到的数据加入到队列中。在载入界面时会打开数据解析线程,当队列中有数据时,数据解析线程会解析数据。遇到的问题是,查看任务管理器发现我的应用程序的cpu占用率达到了25,当我把解析线程注释掉后应用程序的cpu暂用率变为0,这就是解析线程太耗cpu,如图所示。要是最近几年的电脑还不会出现卡顿的现象,但是如果是比较旧的电脑就会出现卡顿的现象了,请问有什么好的方法优化?解析线程源代码如下:
DataDealThread = new Thread(DataDealMethod);
DataDealThread.Start();
private void DataDealMethod()
{
while (true)
{
string strRcv = null;
try
{
if (RcvQueue.Count >= 1)
{
byte[] ReceiveDataDeal = RcvQueue.Dequeue();
//Debug.WriteLine(TCPReceiveDataDeal.Length, "TCPReceiveDataDeal_Length ");
for (int i = 0; i < ReceiveDataDeal.Length; i++) //窗体显示
{
strRcv += ReceiveDataDeal[i].ToString("X2") + " "; //16进制显示
}
RcvTxt01.Text += strRcv + "\r\n";
}
else continue;
}
catch
{
break;
}
}
}
我感觉是解析线程的while循环的问题,因为一般耗cpu的就是while循环,但我想不出如何不使用while来循环不停的处理数据,我的应用程序必须是有数据就解析。。。
希望懂的人能给一点建议或能实现的方法,有源代码更好,多谢。。。
------解决思路----------------------
else continue;
改为
else Thread.Sleep(1);
毕竟你处理数据是非常快的,那么大部分时间队列里其实都没有数据,一旦有数据也在几ns之内处理掉了
那么你就相当于while死循环在空转,能不吃CPU吗
------解决思路----------------------
如果你写else continue;
那么其实根本不需要写else
反正不进if,后面也没有其他代码,还是回到while重新执行
------解决思路----------------------
因为在做一个死循环的判断
------解决思路----------------------
Sleep(1) 将使计算频率降到每秒1千次,如果省掉,则以一个CPU100%的马力,会不会达到每秒1亿次以上?很容易理解的.
直接用serialPort_DataReceived事件来实现控制是最好的,如果一定要用一个线程,不妨用AutoResetEvent来同步.
------解决思路----------------------
Sleep(1) 并不会让你的程序真的休眠1毫秒然后执行,因为windows的机制根本不是1毫秒以内就切换一次线程的。因此你写 Sleep(1),这是一种“自我安慰法”,实际上会等待十几倍甚至几十倍的时间之后才继续运行。
多线程处理程序,当有数据需要处理时,向系统线程池里注册一个处理过程(它包括要处理的数据)就行了。系统线程池本身就是一个队列,而且它知道如何比较好地调度多线程过程。
好的多线程程序,不需要可以出现什么“死循环、阻塞”的代码。你用不着去写什么“任务队列”,更用不着写什么 DataDealThread.Start() 语句。
------解决思路----------------------
可以让你的线程sleep一下。