.Net中的串口操作,避免死锁

串口操作网上应该有大量的文章,这里就不多解释了,在使用SerialPort时,关闭时总会遇到死锁,网上有其他人的代码虽然能解决死锁,但是会陷入一个死循环当中,导致程序不能退出,这篇文章可以解决这个问题,废话少说,直接上代码:

        SerialPort spMain = new SerialPort();  //端口
        bool Listening = false;//是否在读取数据
        bool Closing = false;//是否在关闭串口
        delegate void AddContent(byte[] received);
        event AddContent addContent;

        public SerialTest()
        {
            InitializeComponent();
            InitPort("COM3");
        }

        void InitPort(string portName)
        {
            if (SerialPort.GetPortNames().ToList().IndexOf(portName) == -1)
            {
                MessageBox.Show("没有找到" + portName + "端口!\n");
                return;
            }
            spMain.PortName = portName;
            spMain.DataBits = 8;
            spMain.Parity = Parity.None;
            spMain.StopBits = StopBits.One;
            spMain.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
            this.addContent += new AddContent(ProcessData);
        }

        void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (Closing) return;//如果正在关闭串口,就不读取数据  
            try
            {
                Listening = true;//开始读取数据。
                byte[] readBuffer = new byte[spMain.BytesToRead];
                spMain.Read(readBuffer, 0, readBuffer.Length);

                addContent(readBuffer);
            }
            finally
            {
                Listening = false;//读取数据完毕
                if (Closing) ClosePort(spMain);  //读完数据若需要关闭串口,则调用关闭串口方法,这样就解决了卡在Application.DoEvents()了。
            }
        }
        void ProcessData(byte[] receivedData)
        {
            this.BeginInvoke(new MethodInvoker(delegate {
                txtContent.AppendText(new ASCIIEncoding().GetString(receivedData);
            }));
        }

        private void Open_Click(object sender, EventArgs e)
        {
            if (spMain == null) return;
            if (button1.Text == "开始")
            {
                button1.Text = "停止";

                spMain.Open();
            }
            else
            {
                button1.Text = "开始";
                ClosePort(spMain);
            }
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <param name="sp"></param>
        void ClosePort(SerialPort sp)
        {
            if (sp != null && sp.IsOpen)
            {
                Closing = true;
                if (Listening) return; //如果正在读取数据,则不关闭串口
                sp.Close();
                Closing = false;
            }
        }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值