Ich versuche, von mehreren seriellen Schnittstellen von Sensoren über Mikrocontroller zu lesen. Jeder serielle Port erhält mehr als 2000 Messungen (jede Messung ist 7 Bytes, alle in Hex). Und sie feuern gleichzeitig. Im Moment polle ich von 4 seriellen Ports. Außerdem übersetze ich jede Messung in String und hänge sie an einen Stringbuilder an. Wenn ich mit dem Empfang von Daten fertig bin, werden sie in eine Datei ausgegeben. Das Problem ist, dass der CPU-Verbrauch sehr hoch ist und zwischen 80% und 100% liegt.Serial Port Polling und Datenverarbeitung
Ich ging ein paar Artikel und legte Thread.Sleep (100) am Ende. Es reduziert die CPU-Zeit, wenn keine Daten kommen. Ich setze Thread.Sleep auch am Ende jeder Abfrage, wenn BytesToRead kleiner als 100 ist. Das hilft nur bis zu einem gewissen Grad.
Kann jemand vorschlagen, eine Lösung von der seriellen Schnittstelle abzufragen und Daten zu behandeln, die ich bekomme? Vielleicht hängt jedes Problem, wenn ich etwas bekomme, auf?
//I use separate threads for all sensors
private void SensorThread(SerialPort mySerialPort, int bytesPerMeasurement, TextBox textBox, StringBuilder data)
{
textBox.BeginInvoke(new MethodInvoker(delegate() { textBox.Text = ""; }));
int bytesRead;
int t;
Byte[] dataIn;
while (mySerialPort.IsOpen)
{
try
{
if (mySerialPort.BytesToRead != 0)
{
//trying to read a fix number of bytes
bytesRead = 0;
t = 0;
dataIn = new Byte[bytesPerMeasurement];
t = mySerialPort.Read(dataIn, 0, bytesPerMeasurement);
bytesRead += t;
while (bytesRead != bytesPerMeasurement)
{
t = mySerialPort.Read(dataIn, bytesRead, bytesPerMeasurement - bytesRead);
bytesRead += t;
}
//convert them into hex string
StringBuilder s = new StringBuilder();
foreach (Byte b in dataIn) { s.Append(b.ToString("X") + ","); }
var line = s.ToString();
var lineString = string.Format("{0} ---- {2}",
line,
mySerialPort.BytesToRead);
data.Append(lineString + "\r\n");//append a measurement to a huge Stringbuilder...Need a solution for this.
////use delegate to change UI thread...
textBox.BeginInvoke(new MethodInvoker(delegate() { textBox.Text = line; }));
if (mySerialPort.BytesToRead <= 100) { Thread.Sleep(100); }
}
else{Thread.Sleep(100);}
}
catch (Exception ex)
{
//MessageBox.Show(ex.ToString());
}
}
}
Verwenden Sie keine Schleife. Verwenden Sie bei empfangenen Ereignissen, wenn möglich, oder einem Multimedia-Timer, wenn nicht. –
@HansPassant Ja. – Timtianyang
@DannyVarod Was ist der Multimedia-Timer für in diesem Fall? – Timtianyang