Example #1
0
        public void Scan()
        {
            InvokeStateChanged(1, "配置参数...");

            lock (lockobj)
            {
                if (scanPortTh == null)
                {
                    scanPortTh = new Thread(() =>
                    {
                        while (!stopScan)
                        {
                            lock (managers)
                            {
                                foreach (SerialPortManager m in managers)
                                {
                                    if (m.Connected)
                                    {
                                        continue;
                                    }

                                    m.InvokeStateChanged(2, "扫描设备...");

                                    string[] portNames = SerialPort.GetPortNames();
                                    foreach (string portName in portNames) //遍历已经扫描到的串口
                                    {
                                        //跳过已经使用的串口
                                        if (string.IsNullOrEmpty(portName) || usedPorts.Contains(portName))
                                        {
                                            continue;
                                        }

                                        m.SetSerialPort(ref m._portNum, ref m._baudRate, ref m._parity, ref m._dataBits, ref m._stopBits);
                                        m.userCustomName = m._portNum != -1;

                                        //自定义了串口号
                                        if (m.userCustomName)
                                        {
                                            if (portName != m.PortName)
                                            {
                                                continue;
                                            }
                                        }

                                        SerialPort port = new SerialPort(portName, m._baudRate, m._parity, m._dataBits, m._stopBits);
                                        if (port.DiscardNull)
                                        {
                                            port.DiscardNull = false;
                                        }

                                        bool portOpen = false;
                                        try
                                        {
                                            port.Open(); //打开端口
                                            portOpen = port.IsOpen;
                                            if (portOpen)
                                            {
                                                if (m.VerifySerialPort(port))
                                                {
                                                    port.DataReceived  += m.Port_DataReceived;
                                                    port.ErrorReceived += m.Port_ErrorReceived;
                                                    port.PinChanged    += m.Port_PinChanged;

                                                    m.currentPort = port;
                                                    if (!m.userCustomName)
                                                    {
                                                        m._portName = portName;
                                                    }
                                                    m.Connected = true;
                                                    if (!usedPorts.Contains(portName))
                                                    {
                                                        usedPorts.Add(portName);
                                                    }

                                                    if (managers.All(s => s.Connected))
                                                    {
                                                        stopScan = true;
                                                    }

                                                    m.InvokeStateChanged(3, "捕获设备...");
                                                    break;
                                                }
                                                else
                                                {
                                                    port.Close();
                                                }
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            if (!portOpen)
                                            {
                                                m.InvokeStateChanged(4, "串口被占用!");
                                            }
                                            System.Diagnostics.Debug.WriteLine(ex);
                                            continue;
                                        }
                                    }
                                }
                            }
                            Thread.Sleep(1000);
                        }
                        scanPortTh = null;
                    });
                    scanPortTh.Name         = "scanPortTh";
                    scanPortTh.IsBackground = true;
                }

                if (managers.Any(s => !s.Connected))
                {
                    stopScan = false;
                    if (!scanPortTh.IsAlive)
                    {
                        scanPortTh.Start();
                    }
                }

                if (checkTask == null)
                {
                    checkTask = new Task(() =>
                    {
                        while (true)
                        {
                            try
                            {
                                foreach (SerialPortManager serialPort in managers)
                                {
                                    if (serialPort.Connected == false)
                                    {
                                        continue;
                                    }
                                    if (serialPort.Released)
                                    {
                                        continue;
                                    }

                                    if ((DateTimeHelper.Now - serialPort.lastRecTime).TotalSeconds > 30)
                                    {
                                        serialPort.InvokeStateChanged(-1, "设备断开");
                                        serialPort.Close();
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                LogHelper.WriteError(e, "检查任务失败");
                            }
                            Thread.Sleep(1000);
                        }
                    }, TaskCreationOptions.LongRunning);
                    checkTask.Start();
                }

                if (dealRecDataTh == null)
                {
                    dealRecDataTh = new Thread(() =>
                    {
                        while (true)
                        {
                            try
                            {
                                recQueue.EnqueueEvent.WaitOne(1000);
                                if (recQueue.Count == 0)
                                {
                                    continue;
                                }

                                if (LineReceived != null)
                                {
                                    while (true)
                                    {
                                        int rl = recQueue.Find((byte)'\n'); //查找行尾
                                        if (rl == -1)
                                        {
                                            rl = recQueue.Find((byte)'$');  //特殊情况
                                            if (rl <= 0)
                                            {
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            rl++; //包含\n
                                        }
                                        byte[] tmp = new byte[rl];
                                        int c      = recQueue.DequeueRange(tmp, 0, rl);
                                        OnLineReceived(Encoding.GetString(tmp, 0, c), tmp);
                                    }
                                }
                                else
                                {
                                    recQueue.Clear();
                                }
                            }
                            catch (Exception ex)
                            {
                                LogHelper.WriteError(ex, "处理接收到的串口数据失败");
                            }
                        }
                    });
                    dealRecDataTh.IsBackground = true;
                    dealRecDataTh.Name         = nameof(dealRecDataTh);
                    dealRecDataTh.Start();
                }
            }
        }