C# 串行数据、线程和复选框

C# 串行数据、线程和复选框,c#,multithreading,checkbox,C#,Multithreading,Checkbox,我正在为一个物理课做一个项目,我想尝试用一个应用程序来完成以下任务。测试装置上有一个串行端口,以1 Hz的频率输出数据。我想有一个应用程序,将读取串行端口数据,并保存到一个文件。我已经在一个控制台应用程序中创建了这个,它工作得很好。现在,我想要一个GUI。在GUI的主屏幕上,我想要几个复选框。其中,用户可以向传入的数据流添加时间戳,将数据输出到文本文件,也可以将数据发送到graphite graphing服务器 所以,我在这里寻找一些指针。现在,我有一个连接按钮。按下时,它会打开串行端口并执行s

我正在为一个物理课做一个项目,我想尝试用一个应用程序来完成以下任务。测试装置上有一个串行端口,以1 Hz的频率输出数据。我想有一个应用程序,将读取串行端口数据,并保存到一个文件。我已经在一个控制台应用程序中创建了这个,它工作得很好。现在,我想要一个GUI。在GUI的主屏幕上,我想要几个复选框。其中,用户可以向传入的数据流添加时间戳,将数据输出到文本文件,也可以将数据发送到graphite graphing服务器

所以,我在这里寻找一些指针。现在,我有一个连接按钮。按下时,它会打开串行端口并执行serial.readline(),但如果当前没有数据被推送到链接上,则应用程序会被锁定。所以我假设我需要使用线程。这听起来对吗


最后,我如何处理复选框?我想要总共4个按钮。连接/断开记录/暂停。至少这是我的想法。

不要为串行端口创建线程,而是挂接到事件中

至于复选框,则与事件挂钩

所以它看起来像:

private bool paused;
private SerialPort sp;

public Form1()
{
    InitializeComponent();

    sp = new SerialPort();
    sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
}

private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if (!paused)
    {
        string indata = sp.ReadExisting();

        //Display the data
        //To avoid cross thread problems do something like this
        Invoke(new Action(() =>
        {
            textBox1.Text += indata;
        }));

        //Or if you are just writing to the console 
        Console.WriteLine(indata); //Thread safe

        //Timestamp checkbox
        if (checkBox3.Checked)
        {
            //Display timestamp using DateTime.Now  
        }

    //Write to file checkbox
    if (checkBox4.Checked)
    {
        using (StreamWriter file = new StreamWriter(path, true))
        {
            file.WriteLine(indata);
        } 
    }
}
}

//Pause/Resume Checkbox
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
    paused = checkBox1.Checked;
}

//Connect/Disconnect checkbox
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
    if (checkBox2.Checked)
    {
        sp.Open();
    }
    else
    {
        sp.Close();
    }
}

我怀疑
DataReceived
实际上会在后台线程上引发,因此您需要封送命令以将UI控件更新到UI线程上。不要在DataReceived事件处理程序中使用Invoke,当UI线程关闭端口时,很可能会导致死锁。只使用BeginInvoke。此外,此代码调用的高速率使得UI线程可能会冻结。