当前位置: 代码迷 >> C# >> C# 占用CPU的有关问题
  详细解决方案

C# 占用CPU的有关问题

热度:63   发布时间:2016-05-05 03:52:18.0
C# 占用CPU的问题
使用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重新执行
------解决思路----------------------
引用:
Quote: 引用:

else continue;
改为
else Thread.Sleep(1);

毕竟你处理数据是非常快的,那么大部分时间队列里其实都没有数据,一旦有数据也在几ns之内处理掉了
那么你就相当于while死循环在空转,能不吃CPU吗


引用:
如果你写else continue;
那么其实根本不需要写else
反正不进if,后面也没有其他代码,还是回到while重新执行


多谢回答,就是这个continue的问题,其实可以不写else continue;这条语句的。但神奇的是为什么使用Thread.Sleep(1)之后的CPU暂用率就变成0,即使是有数据解析时的暂用率也只有3-5,太神奇了!!!我感觉即使线程休眠1ms,不停的while循环也会很吃CPU的,给我解答一下吧。原谅我的小白疑惑,我只是不想做知其然,不知其所以然的事。。。再次感谢於黾君的回答!

因为在做一个死循环的判断
------解决思路----------------------
Sleep(1) 将使计算频率降到每秒1千次,如果省掉,则以一个CPU100%的马力,会不会达到每秒1亿次以上?很容易理解的.
直接用serialPort_DataReceived事件来实现控制是最好的,如果一定要用一个线程,不妨用AutoResetEvent来同步.
------解决思路----------------------
Sleep(1)  并不会让你的程序真的休眠1毫秒然后执行,因为windows的机制根本不是1毫秒以内就切换一次线程的。因此你写 Sleep(1),这是一种“自我安慰法”,实际上会等待十几倍甚至几十倍的时间之后才继续运行。

多线程处理程序,当有数据需要处理时,向系统线程池里注册一个处理过程(它包括要处理的数据)就行了。系统线程池本身就是一个队列,而且它知道如何比较好地调度多线程过程。

好的多线程程序,不需要可以出现什么“死循环、阻塞”的代码。你用不着去写什么“任务队列”,更用不着写什么 DataDealThread.Start() 语句。


------解决思路----------------------
可以让你的线程sleep一下。
  相关解决方案