C#串口关闭Close()-线程卡死-解决方法

来源:互联网 发布:网络主播面试什么条件 编辑:程序博客网 时间:2024/05/16 15:07

问题很简单:
1.设置isReceiving 标志位,判断串口读取线程是否在占用资源。
2.设置读写超时,防止卡死在Read()命令里

本人比较懒, 在代码关键修改位置标了/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!/,供大家参考。希望能帮到大家0 0

 class CSerial    {        SerialPort myPort = null;        //委托        public event EventHandler Event_DataReceived;        //接收的容器,不需理会        private byte[] buffer = new byte[1024];        List<byte> byteSource = new List<byte>() { };        private byte[] byte_head = {0xff,0xff};        private object locker = new object();//发送函数线程锁        bool isReceiving = false;/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/        //构造函数        public CSerial(string portName,int baudRate)        {            myPort = new SerialPort(portName,baudRate,Parity.None,8,StopBits.One);            myPort.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);            myPort.ReadTimeout = 1000;/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/            myPort.WriteTimeout = 1000;        }        //设置        public void Set(string portName,int baudRate)        {            myPort.PortName = portName;            myPort.BaudRate = baudRate;        }        //打开        public bool Open()        {            try            {                myPort.Open();                if (!myPort.IsOpen)                {                    return false;                }                return true;            }            catch(Exception ex)            {                 return false;            }        }        //关闭        public bool Close()        {            try            {                if(!myPort.IsOpen)                {                    return true;                }                while (isReceiving) Application.DoEvents();  /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/                myPort.Close();                byteSource.Clear();                if (myPort.IsOpen)                {                    return false;                }                return true;            }            catch (Exception ex)            {                return false;            }        }        public bool Send(string data)        {            lock (locker)            {                try                {                    byte[] WriteBuffer = Encoding.ASCII.GetBytes(data);                    myPort.Write(WriteBuffer, 0, WriteBuffer.Length);                    return true;                }                catch (Exception ex)                {                    Log.write("Send-Error:" + ex.Message);                    return false;                }            }        }        public bool Send(byte[] data)        {            lock (locker)            {                try                {                    myPort.Write(data, 0, data.Length);                    return true;                }                catch (Exception ex)                {                    Log.write("Send-Error:" + ex.Message);                    return false;                }            }        }        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)        {            try            {                isReceiving = true;/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/                int length_reader = myPort.Read(buffer, 0, buffer.Length);                Log.write("Serial-Receive size:" + length_reader.ToString(), 2);                //保存                byte[] byte_receive = new byte[length_reader];                Array.Copy(buffer, byte_receive, length_reader);                byteSource.AddRange(byte_receive);                //byteSource.FindIndex(0,a=>a==0xff);                int iIndex = byteSource.IndexOf(0xff);                if (iIndex == -1)                {                    return;                }//找不到头                while (iIndex != -1)                {                    if (iIndex == byteSource.Count - 1)                    {                        break;                    }//在尾部                    if(byteSource.Count<6)                    {                        break;                    }                    if (byteSource[iIndex + 1] != 0xff)                    {                        break;                    }//头部检测                    byte length_data = byteSource[iIndex + 2];                    if (byteSource.Count() < iIndex+length_data + 6)                    {                        break;                    }//长度不足                    byte[] data_availble = byteSource.GetRange(iIndex, length_data + 6).ToArray();                    byteSource.RemoveRange(iIndex, length_data + 6);                    string strRcv = null;                    for (int i = 0; i < data_availble.Length; i++) //窗体显示                      {                        strRcv += data_availble[i].ToString("X2") + ",";  //16进制显示                      }                    Log.write("Serial-Receive Availble Msg:" + strRcv, 2);                    if (Event_DataReceived != null)                    {                        Event_DataReceived(data_availble, null);                        return;                    }                }            }            catch (Exception ex)            {                Log.write("port_DataReceived-Error:" + ex.Message,0);                byteSource.Clear();            }            finally            {                isReceiving = false;/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/            }        }    }
0 0