SerialPort + CF 2.0 предотвращает потерю данных - PullRequest
1 голос
/ 22 апреля 2009

Может кто-нибудь сказать мне, почему код ниже будет отсутствовать или отбрасывать данные. Я гуглил всю ночь, но не могу найти никаких указателей. последовательный порт использует следующие настройки; 38400, n, 8,1 xon / xoff flow control. ReceivedBytesThreshold = 1.

isReceiving и stockReceived оба являются членами формы

       private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        string dataReceived = serialPort1.ReadExisting();
        bytecount += dataReceived.Length;
        processSerialData(dataReceived);
    }

    private void processSerialData(string dataReceived)
    {
        if (isReceiving == false)
        {
            int stxpos = dataReceived.IndexOf('\x02');
            if (stxpos != -1)
            {
                dataReceived = dataReceived.Replace("\x02", "");
                labelcaption = "Receiving... ";
                this.Invoke(new EventHandler(SetLabel));
                isReceiving = true;
            }
        }

        int etxpos = dataReceived.IndexOf('\x03');
        if (etxpos != -1)
        {
            dataReceived = dataReceived.Replace("\x03", "");
            //tmpFile.Write(dataReceived);
            writeToFile(dataReceived);
            tmpFile.Close();
            isReceiving = false;
            stockReceived = true;
        }

        // Now we need to write the data to file
        if (isReceiving == true)
        {
            if ((bytecount / recordSize) % 100 == 0)
            {
                labelcaption = "Receiving... " + (bytecount / recordSize);
                this.Invoke(new EventHandler(SetLabel));
            }
            //tmpFile.Write(dataReceived);
            writeToFile(dataReceived);
        }
    }

Ответы [ 3 ]

1 голос
/ 22 апреля 2009

Вы не рассматриваете случай получения нескольких STX или ETX в одном пакете DataReceived.

1 голос
/ 22 апреля 2009

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

  • Вы используете строку и затем ищете непечатные символьные данные. Это подозрительная идея обработки IMO. Вы должны получать байты, а затем искать значения байтов. Кто знает, что может делать базовая кодировка, но потеря некоторых символов, особенно если она использует кодировку ASCII, меня не удивит.
  • Это также похоже на потенциальную проблему с потоком. Когда вы получаете событие DataRectained, вы читаете данные, а затем продолжаете и обрабатываете данные в контексте обработчика получения. Что произойдет, если вы получите другое событие, пока еще обрабатываете последнее? Бьюсь об заклад, переменная byteCount будет скрыта. Лично у меня был бы поток, предназначенный для получения данных, и другой для их обработки. По крайней мере, я бы добавил туда какой-нибудь объект синхронизации.
0 голосов
/ 29 октября 2009

Поскольку serialPort1_DataReceived является инициируемым событием, оно происходит только в основном потоке. Поэтому он не может быть введен двумя потоками одновременно. Чтобы доказать это, выведите идентификатор потока исполняющего потока (Thread.CurrentThread.ManagedThreadId).

Вы можете придерживаться буферизации данных в вызове serialPort1_DataReceived. Если вы можете гарантировать «время простоя» активности в последовательном канале, буферизуйте до тех пор, пока не узнаете, когда это произойдет, а затем запустите обработку.

например. данные поступят до X байтов / символов. Тогда другой набор символов не будет входить в течение 500 мс. Затем у вас есть 500 мс для обработки полученных байтов.

...