簡體   English   中英

在c#中使用線程讀取COM端口

[英]Read com ports using threading in c#

我想要一些關於線程的建議,因為我是新手。 我已經閱讀了幾篇關於在線線程的文章。

我在讀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組件。 因此,您必須調用this.Invoke,它將對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#中的標准。 另一點如果該方法僅在類中調用,則應將其設為私有。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM