我正处于项目中间,我必须从Arduino的传感器中读取CSV格式的串行数据,使用C#解析获得的值,并显示实时图形。
我是多线程概念的新手,我对应该制作多少线程以及应该分配每个线程的任务感到困惑。
有什么建议吗? 这是一个初始示例代码,因此可能有错误。
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
RxString = serialPort1.ReadExisting();
RxString = RxString.Replace("$", "");
this.Invoke(new EventHandler(DisplayText));
}
//display the parsed string List
private void DisplayText(object sender, EventArgs e)
{
richTextBox1.AppendText(RxString);
GlobalList.AddRange(parsed());
richTextBox2.Text = String.Join(Environment.NewLine, GlobalList);
}
//set the input rate
private void Start_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM32";
serialPort1.BaudRate = 9600;
serialPort1.DtrEnable=true;
serialPort1.Open();
if (serialPort1.IsOpen)
{
Start.Enabled = false;
Stop.Enabled = true;
richTextBox1.ReadOnly = false;
}
}
public List<String> parsed()
{
string line;
int loc = 0;
List<string> stringList;
line = richTextBox1.Text;
stringList = new List<string>(line.Split(','));
richTextBox3.AppendText("\n Pressure:" + stringList[loc]);
loc++;
richTextBox3.AppendText("\n Accelerometer:" + stringList[loc]);
loc++;
richTextBox3.AppendText("\n Temperature:" + stringList[loc]);
loc++;
richTextBox3.AppendText("\n Height:" + stringList[loc]);
loc++;
return stringList;
}
//plot an elementary graph from the values obtained
public void displayglobal()
{
for (int i = 0; i < GlobalList.Count; i++)
{
if (i % 3 == 0)
{
rtxtConsole.AppendText("\nPressure: " + GlobalList[i]);
chart1.Series["tempvspressure"].Points.AddXY(GlobalList[i], GlobalList[i + 2]);
}
}
}
答案 0 :(得分:0)
我强烈建议在任何可以阻止的工作线程上使用工作线程,因为这会冻结用户界面。
我会分离一个线程来读取传入的流并解析数据单元。如果流是CSV,则流解析器可以使用行分隔符(通常是新行)来分隔单位。
如果每行的工作负载非常低,则流读取线程只需调用UI线程,以便在每次具有完整的数据单元时进行处理。如果正在处理的行数导致UI锁定,则可能需要另一个工作线程将它们批量插入UI。为此,您需要一个线程安全队列。
我在监听网络流的日志记录应用程序中已经多次这样做了,而且串口的问题似乎并不相同。
答案 1 :(得分:0)
使用C#中的新async
支持,您根本不需要多个线程。
您可以使用port.BaseStream.ReadAsync()
来配合UI消息处理。