串口读取+线程或更好的东西

本文关键字:更好 读取 线程 串口 | 更新日期: 2023-09-27 18:11:42

我不知道这是否是一个很好的方法来处理这个任务的堆栈,但我确信有一个更快的方法…我从我的微控制器得到数据,但数据长度并不总是相同的长度。我想也许我可以把数据放入堆栈中,然后在线程中取出它,解码消息。我不想减慢DataReceivedHandler,所以我创建了一个线程,可以弹出数据,并在我的decodeMessage()函数中写入我的Listview。

过了一会儿,我得到了一个系统。outofmemory异常. .

有什么更好的方法吗?

当数据到达这里时,我正在从我的串行端口读取:

Stack<byte[]> stack = new Stack<byte[]>();

public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    byte[] data = new byte[sp.BytesToRead];
    sp.Read(data, 0, data.Length);
    stack.Push(data);
}

这是我的线程:

private void formatData()
{
    try
    {
        while (true)
        {
            byte[] data;
            int i=0;
            Dispatcher.BeginInvoke(new Action(() =>
            {
                while (stack.Count > 0)
                {
                    data = stack.Pop();
                    while (i < data.Length)
                    {
                        decodeMessage(data[i]);
                        i++;
                    }
                }
            }));          
        }
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

thx

串口读取+线程或更好的东西

此代码使用线程安全队列。我简化了自己的一些代码,因此这些代码没有经过测试或编译。如果你在编译时遇到问题或者产生错误,请给我留言,我将帮助你解决。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Windows.Threading;
using System.Collections.Concurrent;
void someRoutine()
{
    // initialize queue before using it
    serialDataQueue = new ConcurrentQueue<char>();
}

/// <summary>
/// data from serialPort is added to the queue as individual chars, 
/// a struct may be better
/// </summary>
public ConcurrentQueue<char> serialDataQueue;
// get data
void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = sender as SerialPort;
    int bytesAvailable = sp.BytesToRead;
    // array to store the available data    
    char[] recBuf = new char[bytesAvailable];
    try
    {    
        // get the data
        sp.Read(recBuf, 0, bytesAvailable);
        // put data, char by char into a threadsafe FIFO queue
        // a better aproach maybe is putting the data in a struct and enque the struct        
        for (int index = 0; index < bytesAvailable; index++)
           serialDataQueue.Enqueue(recBuf[index]);
    }
    catch (TimeoutException ex)
    {
        // handle exeption here
    }
}

/// <summary>
/// Check queue that contains serial data, call this 
/// routine at intervals using a timer or button click
/// or raise an event when data is received
/// </summary>
private void readSearialDataQueue()
{
    char ch;
    try
    {
        while (serialDataQueue.TryDequeue(out ch))
        {
            // do something with ch, add it to a textbox 
            // for example to see that it actually works
            textboxDataReceived.Text += ch;
        }
    }
    catch (Exception ex)
    {
        // handle ex here
    }
}