在c#中使用线程读取com端口



我想要一些关于线程的建议,因为我是新手。我在网上读了几篇关于线程的文章。

我正在读取com端口数据。我想使用线程,这样它将每5秒读取数据并更新列表框上的数据。目前,正在读取所有数据。我不确定从哪里开始。

我应该开始把我的线程代码?我使用的是Windows Form,c# VS2008。

以下是我从com端口读取数据的代码:
    void datareceived(object sender, SerialDataReceivedEventArgs e)
    {            
        myDelegate d = new myDelegate(update);
        listBox1.Invoke(d, new object[] { });
    }

    public void update()
    {           
        while (serialPortN.BytesToRead > 0)
            bBuffer.Add((byte)serialPortN.ReadByte());
        ProcessBuffer(bBuffer);
    }
    private void ProcessBuffer(List<byte> bBuffer)
    {            
        int numberOfBytesToRead = 125;
        if (bBuffer.Count >= numberOfBytesToRead)
        {            

                listBox1.Items.Add("SP: " + (bBuffer[43].ToString()) + "  " + " HR: " + (bBuffer[103].ToString()));

            // Remove the bytes read from the list
            bBuffer.RemoveRange(0, numberOfBytesToRead);
        }
    }        

谢谢!

为什么不使用计时器呢?将其放入表单的InitializeComponent方法中,

using System.Timers;
private void InitializeComponent()
{
    this.components = new System.ComponentModel.Container();
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.Text = "Form1";
    Timer timer = new Timer();
    timer.Interval = 5000;
    timer.Elapsed += new ElapsedEventHandler(TimerElapsed);
    //timer.Enabled = true; // you may need this, but probably not if you are calling the start method.
    timer.Start();
}
void TimerElapsed(object sender, ElapsedEventArgs e)
{
    // put your code here to read the COM port
}

这段代码的另一个问题是,你会得到一个异常,跨线程操作无效。

你必须像这样修改你的代码,

private void ProcessBuffer(List<byte> bBuffer)
{
    int numberOfBytesToRead = 125;
    if (bBuffer.Count >= numberOfBytesToRead)
    {
        this.Invoke(new Action(() =>
        {
            listBox1.Items.Add("SP: " + (bBuffer[43].ToString()) + "  " + " HR: " + (bBuffer[103].ToString()));
        });
        // Remove the bytes read from the list
        bBuffer.RemoveRange(0, numberOfBytesToRead);
    }
}

原因是ProcessBuffer方法将在后台线程上运行。后台线程不能访问UI线程上的UI组件。所以你要叫它。调用,它将在UI线程上运行更新到列表框。

如果您想了解更多关于Invoke方法的信息,请查看这里,

http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

更新:

所以在TimerElapsed方法中,你会想调用你的代码,但它不清楚我应该调用你的代码的哪一部分?什么是'datareceived'方法,在你的代码片段中没有调用它。

所以我猜它会是这个

void TimerElapsed(object sender, ElapsedEventArgs e)
{
    Update();
}
public void Update()
{
    while (serialPortN.BytesToRead > 0)
        buffer.Add((byte)serialPortN.ReadByte());
    ProcessBuffer(buffer);
}

它没有意义,因为它调用ProcessBuffer方法,因为缓冲区将来自哪里?

如果我没有在正确的轨道上可能扩展您的代码示例,我很乐意帮助更多。

请注意我对你的代码做了一些风格上的改变(你可以随意接受或放弃),c#中的方法应该以大写字母开头,调用变量bBuffer在c#中不是标准的。另外,如果该方法只能从类中调用,则应该将其设为private。

最新更新