【问题标题】:CPU usage problemCPU使用问题
【发布时间】:2011-08-17 07:48:37
【问题描述】:

我有一个网络项目,里面没有计时器。只是一个连接到服务器并监听从网络接收任何数据的 tcpclient。

         TcpClient _TcpClient = new TcpClient(_IpAddress, _Port);
        _ConnectThread = new Thread(new ThreadStart(ConnectToServer));
        _ConnectThread.IsBackground = true;
        _ConnectThread.Start();


    private void ConnectToServer()
    {
        try
        {
            NetworkStream _NetworkStream = _TcpClient.GetStream();
            byte[] _RecievedPack = new byte[1024 * 1000];
            string _Message = string.Empty;
            int _BytesRead;
            int _Length;

            while (_Flage)
            {
                _BytesRead = _NetworkStream.Read(_RecievedPack, 0, _RecievedPack.Length);
                _Length = BitConverter.ToInt32(_RecievedPack, 0);
                _Message = UTF8Encoding.UTF8.GetString(_RecievedPack, 4, _Length);

                if (_BytesRead != 0)
                {
                    //call a function to manage the data

                    _NetworkStream.Flush();
                }
            }
        }
        catch (Exception exp)
        {                
            // call a function to alarm that connection is false
        }
    }

但过了一会儿,我的应用程序的 CPU 使用率上升了(90%、85%、...)。 即使没有收到数据。

谁能给我一些关于cpu使用的提示。我完全空白。我不知道我应该检查项目的哪一部分!

【问题讨论】:

  • 我对代码有点困惑——你没有检查_BytesRead,但这似乎是其余数据的基础——否则你不知道你是否有完整的消息...?还有——看书时为什么脸红?

标签: c# .net networking tcpclient


【解决方案1】:

谁能给我一些关于cpu使用的提示

您应该考虑检查应用程序中的循环,例如while 循环,如果您花费大量时间等待某个条件变为真,那么这将占用大量 CPU 时间。比如

while (true)
{}

while (_Flag)
{
    //do something
}

如果在 while 内执行的代码是同步的,那么线程将结束占用大量 CPU 周期。为了解决这个问题,你可以在不同的线程中执行while里面的代码,所以它是异步的,然后在操作执行时使用ManualResetEventAutoResetEvent来报告,另外要提到的是考虑使用@987654326 @方法直到线程休眠并给cpu时间来执行其他线程,例如:

while(_Flag)
{
    //do something

    Thread.Sleep(100);//Blocks the current thread for 100 milliseconds
}

【讨论】:

    【解决方案2】:

    您的代码有几个问题......最重要的是恕我直言:

    • 使用异步方法(BeginRead 等),而不是阻塞方法,并且不要创建自己的线程。线程是“昂贵的>”资源——因此在线程中使用阻塞调用是一种资源浪费。使用异步调用可以让操作系统在发生事件(例如接收到的数据)时回叫您,因此不需要单独的线程(回调使用池线程运行)。
    • 注意Read可能只返回几个字节,它不必填充_ReceivedPackbuffer。从理论上讲,它可能只接收一两个字节 - 甚至不足以让您致电 ToInt32

    【讨论】:

      【解决方案3】:

      CPU 使用率达到峰值,因为您有一个 while 循环,如果它没有从网络接收任何内容,它不会执行任何操作。最后加上Thread.Sleep(),如果没有收到数据,你的CPU使用率就正常了。

      并接受卢塞罗给你的建议。

      【讨论】:

        【解决方案4】:

        我怀疑当while 循环仍在运行时,连接的另一端已关闭,在这种情况下,您将重复从网络流中读取零字节(标记连接已关闭;请参阅NetworkStream.Read on MSDN)。

        由于NetworkStream.Read 将立即返回(根据 MSDN),因此您将陷入一个紧凑的 while 循环,这将消耗大量处理器时间。尝试添加 Thread.Sleep() 或在循环中检测“零读取”。理想情况下,您也应该通过终止连接来处理零字节的读取。

        while (_Flage)
        {
            _BytesRead = _NetworkStream.Read(_RecievedPack, 0, _RecievedPack.Length);
            _Length = BitConverter.ToInt32(_RecievedPack, 0);
            _Message = UTF8Encoding.UTF8.GetString(_RecievedPack, 4, _Length);
        
            if (_BytesRead != 0)
            {
                //call a function to manage the data
        
                _NetworkStream.Flush();
            }
        }
        

        【讨论】:

          【解决方案5】:

          您是否附加了调试器并单步执行代码以查看其行为是否符合您的预期?

          或者,如果您有可用的分析工具(例如ANTs),那么这将帮助您了解您的应用程序花费的时间。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-01-04
            • 2014-08-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多