C#串口通信高速向下位机发送数据出现内存不断增加

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;

namespace MSPCS
{
///
/// 通讯端口,用于和上位机通讯
/// 上行与下行使用同一种格式:
///
/*
同步头 6 Byte EB90EB90EB90H
设备地址 1 Byte DevAddr
长度 1 Byte (N+2)
命令码 1 Byte CmdCode
数据区 N Byte DATA(1),..,DATA(N)
校验码 1 Byte 累加和求余(除FF)
*
* 00H 数据接收正确(下行)
01H 数据接收错误(下行)
02H 取测量值
03H 取参数
04H 设置参数
05H 设置时间
06H 设备异常码(下行)
7FH 设备状态正常(上行)
*/
///
/// 端口类
///
public class ComPort : SerialPort, IDisposable
{
public event EventHandler NewSerialDataRecieved;
public event EventHandler TimeOutHandler;

    public event EventHandler  Receiving;
    public event EventHandler  ReceiveFinish;

    public event EventHandler  Uploading;
    public event EventHandler  UploadFinish;

    static byte[] ErrorCode = { 0xEB, 0x90, 0xEB, 0x90, 0xEB, 0x90, 0x00, 0x00, 0x7F };
    #region  构造函数
    public ComPort()
        : base()
    {
        Init();
    }

    public ComPort(System.ComponentModel.IContainer container)
        : base(container)
    {
        Init();
    }

    private void Init()
    {
        base.PortName = "COM2";
        base.BaudRate = 9600;
        base.DataBits = 8;
        base.StopBits = StopBits.One;
        base.Parity = Parity.None;            
        base.ReadTimeout = SerialPort.InfiniteTimeout;
        base.ReadBufferSize = 1024;
        base.WriteBufferSize = 512;
        base.WriteTimeout = 1000;

        base.DataReceived += new SerialDataReceivedEventHandler(OnDataReceived);
    }
    #endregion


    #region Methods
    /// <summary>
    /// 开始监听
    /// </summary>
    public void StartListening()
    {
        try
        {
            if (!this.IsOpen)  // 如果端口没有打开,就打开
            {
                this.Open();
            }              
        }
        catch
        {
            MessageBox.Show("上位机通讯端口错误!",
                "SPC工作站",
                MessageBoxButtons.OK,
                MessageBoxIcon.Hand,
                MessageBoxDefaultButton.Button1);
        }
    }      
    #endregion


    /// <summary>
    /// 读取消息
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>

    protected void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
    {





        try
        {
            if (null != Receiving)
            {

// Receiving(sender, null);
}
//byte[] data = new byte[base.BytesToRead];
//base.Read(data, 0, base.BytesToRead);

            //同步头            6 Byte     EB90EB90EB90H
            //设备地址          1 Byte     DevAddr
            //长度        cton        1 Byte      (N+2)               
            byte[] dataInfo = new byte[8];

            dataInfo[0] = Convert.ToByte(base.ReadByte());
            if (0xEB != dataInfo[0])
            {

                base.DiscardInBuffer();
                dataInfo = null;
                return;
            }
            dataInfo[1] = Convert.ToByte(base.ReadByte());
            if (0x90 != dataInfo[1])
            {

                base.DiscardInBuffer();
                dataInfo = null;
                return;
            }
            dataInfo[2] = Convert.ToByte(base.ReadByte());
            if (0xEB != dataInfo[2])
            {

                base.DiscardInBuffer();
                dataInfo = null;
                return;
            }
            dataInfo[3] = Convert.ToByte(base.ReadByte());
            if (0x90 != dataInfo[3])
            {

                base.DiscardInBuffer();
                dataInfo = null;
                return;
            }
            dataInfo[4] = Convert.ToByte(base.ReadByte());
            if (0xEB != dataInfo[4])
            {

                base.DiscardInBuffer();
                dataInfo = null;
                return;
            }
            dataInfo[5] = Convert.ToByte(base.ReadByte());
            if (0x90 != dataInfo[5])
            {

                base.DiscardInBuffer();
                dataInfo = null;
                return;
            }
            base.Read(dataInfo, 6, dataInfo.Length - 6);


           // base.Read(dataInfo, 0, dataInfo.Length);   
            int len = Convert.ToInt32(  dataInfo[7] );
            if (len > 0)
            {
                byte[] data = new byte[8 + len];
                dataInfo.CopyTo(data,0);

                for (int i = 0; i < len; i++)
                {
                    data[8 + i] = Convert.ToByte(   base.ReadByte() );
                }

                base.DiscardInBuffer();

                if (NewSerialDataRecieved != null)
                {
                    NewSerialDataRecieved(this, new ComDataEventArgs(data));
                }


                if (null != ReceiveFinish )
                {
                    ReceiveFinish(sender, null);

                }

            }
        }



        catch  //(Exception ex)
        {
            if (null != TimeOutHandler)
            {
                TimeOutHandler(this, null);


            }
            return;
            // MessageBox.Show("获取端口数据错误:" + ex.Message);
            //if (NewSerialDataRecieved != null)
            //{
            //    NewSerialDataRecieved(this, new ComDataEventArgs(ErrorCode));
            //}
        }
     }


    #region

    /// <summary>
    /// 发送数据
    /// </summary>
    /// <param name="result"></param>
    public void SendData(byte[] result)
    {
        try
        {
            if (null != Uploading)
            {
                Uploading(this, null);
            }

            base.DiscardOutBuffer();
            base.Write(result, 0, result.Length);

            if (null != UploadFinish)
            {
                UploadFinish(this, null);
            }
        }
        catch(Exception ex)
        {
            base.DiscardOutBuffer();
            MessageBox.Show(ex.Message);
        }
    }

    #endregion
}

/// <summary>
/// 数据读取消息事件
/// 把二进制值转化为测量结果。
/// </summary>
public class ComDataEventArgs : EventArgs
{
    public ComDataEventArgs(byte[] data)
    {
        Request = data;           
    }

    /// <summary>
    /// Byte array containing data from serial port
    /// </summary>
    public byte[] Request;
}

}
应用程序是在CE系统上运行的,用10ms间隔重复发送数据,CE任务管理器显示内存不断增加,CPU100%。一直发送到最后,程序会卡死。注释掉 base.DataReceived += new SerialDataReceivedEventHandler(OnDataReceived);就跟程序刚启动一样了,任务管理器显示的情况一样了,只是耗了小部分内存。求大牛指点。

2个回答

DiscardInBuffer怎么实现的?

jay362300
jay362300 DiscardInBuffer是直接调用serialport里面的,我把onDataReceived函数里的处理都注释掉,就一个空函数体,这样发送数据也会使内存不断增加
大约 5 年之前 回复

资源没有释放。自己对比检查一下

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问