/// <summary> /// 串口异步回调监听(全双工模式) /// </summary> /// <param name="AscallBack"></param> /// <returns></returns> public bool BeginListening(AsyncSerailCallback AscallBack) { if (!spCom.IsOpen) { return(false); } stopReceive = false; spCom.DiscardInBuffer(); spCom.DiscardOutBuffer(); System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(fullDuplexReadReceive), (object)AscallBack); return(true); }
/// <summary> /// 全双工读取缓冲区数据 /// <param name="asc">异步回调函数指针</param> /// </summary> private void fullDuplexReadReceive(object asc) { AsyncSerailCallback callback = null; if (asc != null) { callback = (AsyncSerailCallback)asc; } if (!spCom.IsOpen) { return; } List <byte> tmpList = new List <byte>(); while (!stopReceive) { mre.Reset(); //线程标志 byte[] tmpbuff; DateTime dt1 = DateTime.Now; bool isRead = false; //lock (ThreadObject) //串口互斥(防止多线程操作的时候,该接收线程还在运行,其他线程关闭串口的情况发生) //{ while (TimeSub(DateTime.Now, dt1) < (double)byteTimeOut) //字节间最大等待超时时间 { if (stopReceive) { break; //如果停止了就直接退出 } if (isHalfDuplex) //如果是开启了半双工,一问一答 { while (spCom.BytesToWrite > 0) { System.Threading.Thread.Sleep(2); } } if (spCom.BytesToRead > 0) { isRead = false; tmpbuff = new byte[spCom.BytesToRead]; //创建一个长度大小为缓冲区等待接收数据长度的数组 spCom.Read(tmpbuff, 0, tmpbuff.Length); //读取Buff tmpList.AddRange(tmpbuff); //将读出来的数据放到一个字节列表中,方便操作和转换追加 if (frameAnalysis != null) { int vstart, vlen; if (frameAnalysis.FrameAnalysis(tmpList.ToArray(), out vstart, out vlen)) { mre.Set(); //线程标志可被终止 try { if (callback != null) { if (!isHalfDuplex) //如果是全双工方式,则使用新线程去调用回调函数 { Action <object> threadmethod = delegate(object obj) { byte[] bytarr = (byte[])obj; callback(bytarr); }; System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(threadmethod), tmpList.GetRange(vstart, vlen).ToArray()); } else { callback(tmpList.GetRange(vstart, vlen).ToArray()); } } else { lock (ThreadreadQueueObj) { readQueueBuff.Enqueue(tmpList.GetRange(vstart, vlen).ToArray()); //在返回队列中插入一帧 } } } catch { throw new Exception("拆帧接口长度参数返回下标越界..."); } tmpList.RemoveRange(9, vstart + vlen); isRead = true; } } dt1 = DateTime.Now; //重置计时器 } } mre.Set(); //线程标志可被终止 if (tmpList.Count > 0 && !isRead) { if (callback != null) { if (!isHalfDuplex) //如果是全双工方式,则使用新线程去调用回调函数 { Action <object> threadmethod = delegate(object obj) { byte[] bytarr = (byte[])obj; callback(bytarr); }; System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(threadmethod), tmpList.ToArray()); } else { callback(tmpList.ToArray()); } } else { lock (ThreadreadQueueObj) { readQueueBuff.Enqueue(tmpList.ToArray()); } } tmpList.Clear(); } //} } }