В настоящее время я пишу приложение, которое обменивается данными со встроенным сервоприводом через последовательное соединение.
Двигатель отправляет данные о положении со скоростью до 1000 раз в секунду. Я пытаюсь достичь того, чтобы иметь возможность форматировать возвращаемые данные (удаляя из них пробелы, новые строки и т. Д.) И анализируя их для извлечения соответствующих данных из полученных строк.
В настоящее время у меня есть обработчик событий полученных данных считывает данные, форматирует их, используя серию вызовов метода string.replace, и добавляет их к строке, которая действует как буфер. Затем, используя потоки, я постоянно проверяю буфер по мере его заполнения для определенного разделителя (в моем случае "\ r"), который означает конец одного сообщения от двигателя, затем удаляю это сообщение из буфера и распечатываю его в расширенном текстовое поле.
У этого подхода есть две проблемы. Во-первых, поскольку двигатель передает данные о местоположении с такой высокой скоростью, буфер заполняется быстрее, чем данные могут быть обработаны потоками. Таким образом, когда я посылаю команду на двигатель, он действует немедленно, но ответ задерживается на несколько секунд, потому что все предыдущие данные в буфере должны быть обработаны в первую очередь. Во-вторых, наличие двух потоков, выполняющих метод, реализующий структуру while (true), означает, что загрузка процессора резко возрастает, и в течение нескольких секунд вентиляторы на ПК работают на максимум.
Есть ли лучший способ обработки данных?
Вот мой код обработчика событий:
//data recieved event handler
private void dataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string tmp;
tmp = sp.ReadExisting();
//cut out any unnecessary characters
tmp = tmp.Replace("\n", "");
tmp = tmp.Replace(",", "\r");
tmp = tmp.Replace(" ", "");
lock (this)
{
//put all received data into the read buffer
readBuffer += tmp;
}
}
Вот метод, который выполняется потоками:
private void parseBuffer()
{
while (true)
{
//obtain lock, parse one message from buffer
lock (this)
{
if (readBuffer.IndexOf("\r") > 0)
{
String t = readBuffer.Substring(0, readBuffer.IndexOf("\r") + 1);
readBuffer = readBuffer.Replace(t, "");
dataReady(this, new CustomEventArgs(t, null));
}
}
}
}