在创建读取串行数据和绘制图形的GUI的同时实现线程

时间:2013-03-20 07:04:45

标签: c# multithreading graph serial-port backgroundworker

我正处于项目中间,我必须从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]);
            }


        }
    }

2 个答案:

答案 0 :(得分:0)

我强烈建议在任何可以阻止的工作线程上使用工作线程,因为这会冻结用户界面。

我会分离一个线程来读取传入的流并解析数据单元。如果流是CSV,则流解析器可以使用行分隔符(通常是新行)来分隔单位。

如果每行的工作负载非常低,则流读取线程只需调用UI线程,以便在每次具有完整的数据单元时进行处理。如果正在处理的行数导致UI锁定,则可能需要另一个工作线程将它们批量插入UI。为此,您需要一个线程安全队列。

我在监听网络流的日志记录应用程序中已经多次这样做了,而且串口的问题似乎并不相同。

答案 1 :(得分:0)

使用C#中的新async支持,您根本不需要多个线程。

您可以使用port.BaseStream.ReadAsync()来配合UI消息处理。