开发者

CPU usage problem

I have a network project, there is no timer in it. just a tcpclient that connect to a server and listen to receive any data from network.

         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 = st开发者_StackOverflowring.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
        }
    }

But after a while the cpu usage of my application goes up(90%, 85%,...). even if no data receive.

could anybody give me some tips about cpu usage. I'm totally blank. i don't know i should check which part of the project!


could anybody give me some tips about cpu usage

You should consider checking the loops in the application, like while loop, if you are spend so much time waiting for some condition to became true, then it will take much CPU time. for instance

while (true)
{}

or

while (_Flag)
{
    //do something
}

If the code executed inside the while are synchronous, then the thread will be ending eating much of CPU cycles. to solve this problem you could executes the code inside the while in a different thread, so it will be asynchronous, and then use ManualResetEvent or AutoResetEvent to report back when operation executed, another thing to mentioned is to consider using System.Threading.Thread.Sleep method to till the thread to sleep and give the cpu time to execute other threads, example:

while(_Flag)
{
    //do something

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


There are several issues with your code... the most important ones are IMHO:

  • Use async methods (BeginRead etc.), not blocking methods, and don't create your own thread. Thread are "expensive>" resources - and using blocking calls in threads is therefore a waste of resources. Using async calls lets the operating system call you back when an event (data received for instance) occured, so that no separate thread is needed (the callback runs with a pooled thread).
  • Be aware that Read may return just a few bytes, it doesn't have to fill the _ReceivedPackbuffer. Theoretically, it may just receive one or two bytes - not even enough for your call to ToInt32!


The CPU usage spikes, because you have a while loop, which does not do anything, if it does not receive anything from the network. Add Thread.Sleep() at the end of it, if not data was received, and your CPU usage will be normal.

And take the advice, that Lucero gave you.


I suspect that the other end of the connection is closed when the while loop is still running, in which case you'll repeatedly read zero bytes from the network stream (marking connection closed; see NetworkStream.Read on MSDN).

Since NetworkStream.Read will then return immediately (as per MSDN), you'll be stuck in a tight while loop that will consume a lot of processor time. Try adding a Thread.Sleep() or detecting a "zero read" within the loop. Ideally you should handle a read of zero bytes by terminating your end of the connection, too.

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


Have you attached a debugger and stepped through the code to see if it's behaving in the way you expect?

Alternatively, if you have a profiling tool available (such as ANTs) then this will help you see where time is being spent in your application.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜