В настоящее время я пишу приложение, которое взаимодействует со встроенным сервоприводом через последовательное соединение.
Двигатель отправляет данные о положении со скоростью до 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));
}
}
}
}
textBox1.text += myText;. При печати на консоль у меня нет проблем с ростом буфера быстрее, чем программа обрабатывает данные, как я сказал выше. - person isometrik   schedule 13.05.2011