CPU使用问题

时间:2011-08-17 07:48:38

标签: c# .net networking tcpclient

我有一个网络项目,里面没有计时器。只是一个连接到服务器并侦听从网络接收任何数据的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使用的提示。我完全是空白。我不知道我应该检查项目的哪个部分!

5 个答案:

答案 0 :(得分:2)

  

任何人都可以给我一些关于cpu使用的提示

你应该考虑检查应用程序中的循环,比如while循环,如果你花了这么多时间等待某些条件变为真,那么它将需要很多CPU时间。例如

while (true)
{}

while (_Flag)
{
    //do something
}

如果while内部执行的代码是同步的,那么该线程将以大部分CPU周期结束。为了解决这个问题,你可以在不同的线程中执行while内的代码,因此它将是异步的,然后使用ManualResetEventAutoResetEvent报告执行操作的时间,另外要提到的是考虑使用System.Threading.Thread.Sleep方法来使线程进入睡眠状态并给cpu时间执行其他线程,例如:

while(_Flag)
{
    //do something

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

CPU使用率激增,因为如果没有从网络接收任何内容,你有一个while循环,它什么也不做。如果没有收到数据,则在它的末尾添加Thread.Sleep(),并且您的CPU使用率将是正常的。

接受Lucero给你的建议。

答案 3 :(得分:1)

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

由于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();
    }
}

答案 4 :(得分:0)

您是否已附加调试器并逐步执行代码以查看其是否按预期方式运行?

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