Вызов функции из обработчика последовательного порта занял слишком много времени и мощности процессора

#c# #serial-port

#c# #последовательный порт

Вопрос:

я получаю данные из интерфейса последовательного порта, каждый поток данных (пакет) состоит из 1 КБ. эти значения являются базовыми аналоговыми сигналами цифрового осциллографа. После обработки этих данных я вывожу сигналы на экран.

Проблема в том, что если я вызываю функцию, которая обрабатывает сигналы от последовательного порта «DataReceivedHandler», это занимает слишком много времени (200 мс) и слишком много процессорной мощности. Но когда я вызываю свою функцию отдельно, например, через нажатие кнопки, это заняло 10 мс. После отладки слишком много раз я не мог понять, почему это занимает слишком много времени? каковы возможные причины этого? можете ли вы дать мне несколько решений?

В двух приведенных ниже примерах результаты верны, но требуют разных затрат времени.

 public void DataReceivedHandler(
                 object sender,
                 SerialDataReceivedEventArgs e)
{

    SerialPort sp = (SerialPort)sender;
    int temp_buffer_count;
            


    temp_buffer_count = sp.BytesToRead;

    label55.Text  = temp_buffer_count.ToString()   "--";
    serialPort1.Read(readBuffer, uart_count, temp_buffer_count);

    uart_count  = temp_buffer_count;

    if(uart_count>3)
    {
        int dataadet = readBuffer[1] * 256   readBuffer[2]   3;

        if(uart_count>= dataadet)
        {
            if(readBuffer[0]==0xff)
            {
                UdpReceivedData = new byte[dataadet   100];
                Array.Copy(readBuffer, ReceivedData, dataadet);

              
                uart_count = 0;
                dataadet = 0;

                if(ReceivedData[3]==AdcDataIslemi)
                {
                    stopwatch2.Resart();
                    //this function tooks too much time
                    PreparePage(false, true);
                    stopwatch2.Stop();
                }

            }
                 

        }

    }
  

}

если я вызываю ту же функцию нажатием кнопки, эта функция выполняется в 20 раз быстрее.

     private void button2_Click(object sender, EventArgs e)
    {
        stopwatch2.Resart();
        PreparePage(false, true);
        stopwatch2.Stop();
    }
  

Комментарии:

1. Секундомер не является хорошим инструментом для сравнения. Мы также не видим, что делает PeparePage, и поэтому не можем сказать, как два метода его вызова могут повлиять на время выполнения. Однако в целом я бы предложил отделить прием данных от их обработки. Например, с помощью потока данных.

2. Спасибо за ответ. PeparePage выполняет некоторые математические операции с пакетом размером 1 КБ. если я обработаю этот пакет через buton, все будет в порядке. Но внутри DataReceivedHandler что-то требует огромной мощности процесса. Я также попробовал таймер. вместо вызова PeparePage я запустил таймер и через 1000 мс, когда таймер сработал, я вызвал PeparePage. но опять ничего не изменилось и все равно заняло огромное время.

3.Опять же, не могу сказать. Как есть, я бы предположил button2_Click , что вызовы PreparePage в потоке пользовательского интерфейса, в то время DataReceivedHandler как нет. Это может быть частью чуда. При использовании таймера зависит от того, какой тип таймера. Есть System.Windows.Forms.Timer , System.Timers.Timer и System.Threading.Timer

4. вы правы, еще раз спасибо.

5. Вы не должны выполнять сложную математику в вашем событии DataReceived, это приведет к его замедлению и / или неправильной работе. Вам нужен отдельный поток, где вы выполняете сложную математику.