Что произойдет, если событие произойдет снова, когда первый не завершит обработку - PullRequest
0 голосов
/ 11 июня 2018

Мой вопрос касается события DataReceived из System.IO.SerialPort.У меня есть метод, который вызывается, когда это событие происходит.Я читаю Данные с myPort.ReadExisting, обрабатываю и сохраняю их.Если я получаю определенный символ, данные до этого момента интерпретируются как команда, и запускается другое событие.

Мой вопрос: что произойдет, если я нахожусь в процессе обработки полученных данных, и приходят новые данные?Ожидают ли новые экземпляры метода завершения работы старого?В противном случае это может привести к конфликту, поскольку оба экземпляра этого метода используют одни и те же переменные.Я ошибаюсь в концепции обработки событий или есть элегантный способ справиться с этим.

Мой код работает нормально и мои результаты соответствуют ожиданиям, но моя обработка данных не настолько сложна.Я просто хочу понять эту проблему и избежать проблем в будущем.Мой пример кода будет таким:

private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

        SerialPort port = (SerialPort)sender;
        int index = m_ports.FindIndex(p => p.PortName == port.PortName);
        string tmpData;
        m_currentData[index] += tmpData = port.ReadExisting();
        Console.WriteLine(tmpData);

        string currentData = m_currentData[index];
        string currentOrder = "";
        while (currentData.Contains(orderEndChar))
        {
            int endCharLocation = currentData.IndexOf(orderEndChar);
            currentOrder = currentData.Substring(0, endCharLocation);
            currentData = currentData.Substring(endCharLocation + 1);
            orderEvent.gotOrder(currentOrder);
            //orderEvent.gotOrder(new EventArgs());
        }
        m_currentData[index] = currentData;

}

Списки, потому что я хочу, чтобы он работал с несколькими портами, откуда я могу получать команды.

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

SerialPort.DataReceived вызывается во вторичном потоке.Читайте здесь: https://msdn.microsoft.com/fi-fi/library/system.io.ports.serialport.datareceived(v=vs.110).aspxПоэтому, если у вас прослушивается много экземпляров SerialPort, может случиться так, что одновременно будет запущено более одного Port_DataReceived метода.Но не бойтесь локальных переменных, так как они живут только при вызове определенного метода.Поэтому 3 разных потока, выполняющих один и тот же метод, будут инициировать 3 разные локальные переменные, даже если их имена одинаковыНо будьте осторожны с глобальными переменными.Поскольку Port_DataReceived является синхронным, следующий вызов события для того же SerialPort объекта будет ожидать, поэтому эти вызовы будут выполняться один за другим.

0 голосов
/ 11 июня 2018

Итак, если вы подозреваете, что ваш производитель может работать быстрее, чем ваш потребитель, вы должны отделить их с помощью очереди.

Все, что должен сделать ваш производитель, - это поместить полученные данные в(потокобезопасная) очередь ... быстрая операция, которая не будет переполнена.

Все, что нужно сделать потребителю, - это читать из очереди со своей скоростью.

TPL Dataflow предлагает класс BufferBlock<T>, которыйможет послужить удобной очередью для таких отношений между производителем и потребителем.

Вы можете покопаться немного глубже в потоке данных.Это идеально подходит для производителей / потребителей в асинхронном мире.

Начните здесь: https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-write-messages-to-and-read-messages-from-a-dataflow-block

...