Проблема использования процессора - PullRequest
3 голосов
/ 17 августа 2011

У меня есть сетевой проект, в нем нет таймера. просто 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
        }
    }

Но через некоторое время загрузка моего приложения возросла (на 90%, 85%, ...). даже если нет данных.

Кто-нибудь может дать мне несколько советов по использованию процессора. Я совершенно пустой я не знаю, я должен проверить, какая часть проекта!

Ответы [ 5 ]

2 голосов
/ 17 августа 2011

Кто-нибудь может дать мне несколько советов по использованию процессора

Вы должны рассмотреть проверку циклов в приложении, например, цикл while, если вы тратите так много времени на ожидание некоторыхусловие станет истинным, тогда это займет много процессорного времени.например,

while (true)
{}

или

while (_Flag)
{
    //do something
}

Если код, выполняемый внутри while, является синхронным, то поток завершит потребление большей части циклов ЦП.Чтобы решить эту проблему, вы можете выполнить код в то время как в другом потоке, так что он будет асинхронным, а затем использовать ManualResetEvent или AutoResetEvent, чтобы сообщить о выполнении операции, еще одна вещь, которую следует упомянуть, это рассмотреть использование System.Threading.Thread.Sleep метод, позволяющий перевести поток в спящий режим и дать процессору время для выполнения других потоков, например:

while(_Flag)
{
    //do something

    Thread.Sleep(100);//Blocks the current thread for 100 milliseconds
}
1 голос
/ 17 августа 2011

Я подозреваю, что другой конец соединения закрыт, когда цикл while все еще работает, и в этом случае вы будете многократно читать нулевые байты из сетевого потока (пометка соединения закрыта; см. NetworkStream.Read на 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();
    }
}
1 голос
/ 17 августа 2011

Скачки использования процессора, потому что у вас есть цикл while, который ничего не делает, если он ничего не получает из сети. Добавьте Thread.Sleep () в конце этого, если не были получены данные, и использование вашего процессора будет нормальным.

И прими совет, который дал тебе Лусеро.

1 голос
/ 17 августа 2011

Есть несколько проблем с вашим кодом ... наиболее важными из них являются IMHO:

  • Используйте асинхронные методы (BeginRead и т. Д.), Не блокируйте методы и не создавайте своисобственный поток.Потоки являются «дорогими>» ресурсами, и поэтому использование блокирующих вызовов в потоках является пустой тратой ресурсов.Использование асинхронных вызовов позволяет операционной системе перезванивать вам, когда происходит событие (например, данные, полученные), поэтому отдельный поток не требуется (обратный вызов выполняется с помощью пула).
  • Помните, что Read может вернуть всего несколько байтов, он не должен заполнять буфер _ReceivedPack.Теоретически, он может просто получить один или два байта - даже недостаточно для вашего звонка на ToInt32!
0 голосов
/ 17 августа 2011

Вы подключили отладчик и пошагово просмотрели код, чтобы увидеть, работает ли он так, как вы ожидаете?

В качестве альтернативы, если у вас есть инструмент профилирования (например, ANTs ), тогда это поможет вам увидеть, где в вашем приложении тратится время.

...