Sto provando a leggere da diverse porte seriali dai sensori tramite microcontrollori. Ogni porta seriale riceverà più di 2000 misurazioni (ogni misura è 7 byte, tutte in esadecimale). E stanno sparando allo stesso tempo. In questo momento sto interrogando da 4 porte seriali. Inoltre, traduco ogni misura in String e aggiungo ad un Stringbuilder. Al termine della ricezione dei dati, verranno inseriti in un file. Il problema è che il consumo della CPU è molto alto, dall'80% al 100%.Polling porta seriale e gestione dati
Sono andato anche se alcuni articoli e messo Thread.Sleep (100) alla fine. Riduce il tempo di CPU quando non ci sono dati in arrivo. Ho anche inserito Thread.Sleep alla fine di ogni polling quando BytesToRead è inferiore a 100. Aiuta solo in una certa misura.
Qualcuno può suggerire una soluzione per il polling dalla porta seriale e gestire i dati che ottengo? Forse aggiungendo ogni volta che ottengo qualcosa causa il problema?
//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());
}
}
}
Non utilizzare un loop. Utilizzare su eventi ricevuti, se possibile, o un timer multimediale, in caso contrario. –
@HansPassant Sì. – Timtianyang
@DannyVarod Qual è il timer multimediale per questo caso? – Timtianyang