void Run()
        {
            Stopwatch sw = new Stopwatch();

            while (true)
            {
                sw.Restart();
                System.Threading.Thread.Sleep(10);
                try
                {
                    #region IO
                    bool[] M2764 = Fx5u_2.ReadMultiM("M2764", 32);
                    Fx5u.SetMultiM("M2564", M2764);
                    #endregion
                    #region 扫码
                    //扫码(载具)【A轨道】
                    if (Fx5u_2.ReadM("M2797"))
                    {
                        this.Dispatcher.Invoke(new Action(() =>
                        {
                            AddMessage("轨道A扫码");
                        }));
                        Fx5u_2.SetM("M2797", false);
                        Fx5u_2.SetMultiM("M2597", new bool[4] {
                            false, false, false, false
                        });
                        ScanA.GetBarCode(ScanAGetBarcodeCallback);
                    }
                    //扫码(载具)【B轨道】
                    if (Fx5u_2.ReadM("M2802"))
                    {
                        this.Dispatcher.Invoke(new Action(() =>
                        {
                            AddMessage("轨道B扫码");
                        }));
                        Fx5u_2.SetM("M2802", false);
                        Fx5u_2.SetMultiM("M2602", new bool[4] {
                            false, false, false, false
                        });
                        ScanB.GetBarCode(ScanBGetBarcodeCallback);
                    }
                    #endregion
                    #region 大数据读取
                    //读报警
                    M300 = Fx5u_2.ReadMultiM("M1100", (ushort)AlarmList.Count);
                    //读三色灯状态
                    LampColor = Fx5u_2.ReadW("D200");
                    #endregion
                }
                catch
                { }
                SWms = sw.ElapsedMilliseconds;
            }
        }
        void ScanBGetBarcodeCallback(string barcode)
        {
            if (barcode != "Error")
            {
                Mysql mysql = new Mysql();
                if (mysql.Connect())
                {
                    string    stm = "SELECT * FROM BODMSG WHERE SCBODBAR = '" + barcode + "' ORDER BY SIDATE DESC LIMIT 0,5";
                    DataSet   ds  = mysql.Select(stm);
                    DataTable dt  = ds.Tables["table0"];
                    if (dt.Rows.Count > 0)
                    {
                        if (dt.Rows[0]["STATUS"] == DBNull.Value)
                        {
                            this.Dispatcher.Invoke(new Action(() =>
                            {
                                AddMessage("板 " + barcode + " 状态栏位为空");
                            }));
                            Fx5u_2.SetM("M2605", true);//载具扫码-未测过【B轨道】
                        }
                        else
                        {
                            if ((string)dt.Rows[0]["STATUS"] == "OFF")
                            {
                                this.Dispatcher.Invoke(new Action(() =>
                                {
                                    AddMessage("板 " + barcode + " 未测试");
                                }));
                                Fx5u_2.SetM("M2605", true);//载具扫码-未测过【B轨道】
                            }
                            else
                            {
                                stm = "SELECT * FROM BARBIND WHERE SCBODBAR = '" + barcode + "' ORDER BY SIDATE DESC LIMIT 0,15";
                                ds  = mysql.Select(stm);
                                dt  = ds.Tables["table0"];
                                if (dt.Rows.Count == 15)
                                {
                                    stm = "INSERT INTO BODMSG (SCBODBAR, STATUS) VALUES('" + barcode + "','OFF')";
                                    int rstnum = mysql.executeQuery(stm);
                                    if (rstnum > 0)
                                    {
                                        this.Dispatcher.Invoke(new Action(() =>
                                        {
                                            AddMessage("板 " + barcode + " 解绑");
                                        }));

                                        short[] result   = new short[15];
                                        bool    checkrst = true;
                                        for (int i = 0; i < 15; i++)
                                        {
                                            DataRow[] drs = dt.Select(string.Format("PCSSER = '{0}'", (i + 1).ToString()));
                                            if (drs.Length == 1)
                                            {
                                                try
                                                {
                                                    result[i] = short.Parse((string)drs[0]["RESULT"]);
                                                }
                                                catch (Exception ex)
                                                {
                                                    this.Dispatcher.Invoke(new Action(() =>
                                                    {
                                                        AddMessage(ex.Message);
                                                    }));

                                                    checkrst = false;
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                this.Dispatcher.Invoke(new Action(() =>
                                                {
                                                    AddMessage("板 " + barcode + " 序号 " + (i + 1).ToString() + "索引数 " + drs.Length.ToString());
                                                }));

                                                checkrst = false;
                                                break;
                                            }
                                        }
                                        if (checkrst)
                                        {
                                            string str;
                                            Fx5u_2.WriteMultD("D1020", result);
                                            str = "B_BordInfo;";
                                            for (int i = 0; i < 15; i++)
                                            {
                                                str += result[i].ToString() + ";";
                                            }
                                            str = str.Substring(0, str.Length - 1);
                                            this.Dispatcher.Invoke(new Action(() =>
                                            {
                                                AddMessage(str);
                                            }));

                                            Fx5u_2.SetM("M2604", true);//载具扫码-已测过【B轨道】
                                        }
                                        else
                                        {
                                            Fx5u_2.SetM("M2605", true);//载具扫码-未测过【B轨道】
                                        }
                                    }
                                    else
                                    {
                                        this.Dispatcher.Invoke(new Action(() =>
                                        {
                                            AddMessage("解绑失败");
                                        }));
                                        Fx5u_2.SetM("M2603", true);//载具扫码NG【B轨道】
                                    }
                                }
                                else
                                {
                                    this.Dispatcher.Invoke(new Action(() =>
                                    {
                                        AddMessage("板 " + barcode + " 记录数目不是15");
                                    }));
                                    Fx5u_2.SetM("M2605", true);//载具扫码-未测过【B轨道】
                                }
                            }
                        }
                    }
                    else
                    {
                        this.Dispatcher.Invoke(new Action(() =>
                        {
                            AddMessage("板 " + barcode + " 信息未录入");
                        }));
                        Fx5u_2.SetM("M2605", true); //载具扫码-未测过【A轨道】
                    }
                    Fx5u_2.SetM("M2602", true);     //载具扫码OK【B轨道】
                }
                mysql.DisConnect();
            }
            else
            {
                this.Dispatcher.Invoke(new Action(() =>
                {
                    AddMessage("扫码失败");
                }));
                Fx5u_2.SetM("M2603", true);//载具扫码NG【B轨道】
            }
        }
        async void CardRun()
        {
            string MODE = ""; int CardStatus; int cardret = 1; int timetick = 0;

            Fx5u_2.SetM("M2606", true);
            CardLockFlag = true;
            CardLockTime = DateTime.Now;
            AddMessage("机台锁定!");
            while (true)
            {
                await Task.Delay(1000);

                #region 刷卡
                try
                {
                    byte[] buf = new byte[256];                                     //用来存储卡信息的buff
                    byte[] snr = 读写器530SDK.CPublic.CharToByte("FF FF FF FF FF FF"); //应该是一种读码格式,照抄即可。
                    if (true)
                    {
                        if (IntPtr.Zero == reader.GetHComm())
                        {
                            string COM = Inifile.INIGetStringValue(iniParameterPath, "读卡器", "COM", "COM19").Replace("COM", "");
                            reader.OpenComm(int.Parse(COM), 9600);
                            MODE = Inifile.INIGetStringValue(iniParameterPath, "读卡器", "MODE", "3");
                        }

                        //刷卡;若刷到卡返回0,没刷到回1。
                        CardStatus = reader.MF_Read(0, byte.Parse(MODE), 0, 1, ref snr[0], ref buf[0]);
                        //采用上升沿信号,防止卡放在读卡机上,重复执行查询动作。寄卡放一次,才查询一次,要再查询,需要重新刷卡。
                        if (cardret != CardStatus)
                        {
                            cardret = CardStatus;
                            if (CardStatus == 0)//刷到卡了
                            {
                                string strTmp = "";
                                //测试发现,卡返回的是16个HEX(十六进制)数,放在byte[]数组内,需要用一下方法转成字符串格式。
                                for (int i = 0; i < 16; i++)
                                {
                                    strTmp += string.Format("{0:X2} ", buf[i]);
                                }
                                //删除转换后,字符串内的空格。这些HEX字符并不是员工编号字符的编码,需要用读到的字符串在数据库里查找,
                                //在记录里再匹配员工信息和权限
                                string barcode = strTmp.Replace(" ", "");
                                AddMessage("刷卡 " + barcode);
                                Oracle oraDB = new Oracle("qddb04.eavarytech.com", "mesdb04", "ictdata", "ictdata*168");
                                if (oraDB.isConnect())
                                {
                                    string    stm = string.Format("SELECT * FROM CAP_TABLE WHERE BARCODE = '{0}'", barcode);
                                    DataSet   s   = oraDB.executeQuery(stm);
                                    DataTable dt  = s.Tables[0];
                                    if (dt.Rows.Count > 0)//查询到数据条目大于0,即查到了
                                    {
                                        //取查到的第一行记录,一般只有1行。如果有多行,也只取第一行。
                                        DataRow dr = dt.Rows[0];
                                        //筛选一下数据,如果我们需要的“工号”、“姓名”和“权限”对应的栏位为空,则数据不合格。
                                        if (dr["OPERATORID"] != DBNull.Value && dr["DATA0"] != DBNull.Value && dr["RESULT"] != DBNull.Value && dr["PARTNUM"] != DBNull.Value)
                                        {
                                            //打印出匹配到的结果,并返回给下位机。
                                            AddMessage("工号 " + (string)dr["OPERATORID"] + " 姓名 " + (string)dr["DATA0"] + " 权限 " + (string)dr["RESULT"]);
                                            if ((string)dr["PARTNUM"] == PM.Text)
                                            {
                                                stm = string.Format("UPDATE CFT_DATA SET BARCODE = '{0}',TRESULT = '{1}',OPERTOR = '{2}',TESTDATE = '{3}',TESTTIME = '{4}',PARTNUM = '{6}' WHERE MNO = '{5}' OR CFT01 = '{5}'",
                                                                    barcode, (string)dr["RESULT"], (string)dr["OPERATORID"], DateTime.Now.ToString("yyyyMMdd"), DateTime.Now.ToString("HHmmss"), _MACID, (string)dr["PARTNUM"]);
                                                int updaterst = oraDB.executeNonQuery(stm);
                                                AddMessage("更新刷卡机台" + updaterst.ToString());
                                                oraDB.executeNonQuery("COMMIT");
                                            }
                                            else
                                            {
                                                AddMessage("人员信息与料号不符");
                                            }
                                        }
                                        else
                                        {
                                            AddMessage("数据库记录信息不完整");
                                        }
                                    }
                                    else
                                    {
                                        AddMessage("未查询到卡信息");
                                    }
                                }
                                oraDB.disconnect();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    reader.CloseComm();
                    AddMessage(ex.Message);
                }
                #endregion
                #region 刷卡恢复
                if (CardLockFlag)
                {
                    try
                    {
                        Oracle oraDB = new Oracle("qddb04.eavarytech.com", "mesdb04", "ictdata", "ictdata*168");
                        if (oraDB.isConnect())
                        {
                            string stm = string.Format("SELECT * FROM CFT_DATA WHERE MNO = '{0}' AND TRESULT = 'PASS' ORDER BY TESTDATE DESC,TESTTIME DESC",
                                                       _MACID);
                            DataSet   ds = oraDB.executeQuery(stm);
                            DataTable dt = ds.Tables[0];
                            if (dt.Rows.Count > 0)
                            {
                                DataRow dr      = dt.Rows[0];
                                string  datestr = (string)dr["TESTDATE"];
                                string  timestr = (string)dr["TESTTIME"];
                                if (datestr.Length == 8 && (timestr.Length == 5 || timestr.Length == 6))
                                {
                                    if (timestr.Length == 5)
                                    {
                                        timestr = "0" + timestr;
                                    }
                                    string datetimestr = string.Empty;
                                    datetimestr = string.Format("{0}/{1}/{2} {3}:{4}:{5}", datestr.Substring(0, 4), datestr.Substring(4, 2), datestr.Substring(6, 2), timestr.Substring(0, 2), timestr.Substring(2, 2), timestr.Substring(4, 2));
                                    DateTime updatetime = Convert.ToDateTime(datetimestr);
                                    if ((updatetime - CardLockTime).TotalMilliseconds > 0)
                                    {
                                        Fx5u_2.SetM("M2606", false);
                                        CardLockFlag = false;
                                        AddMessage("刷卡成功,解锁");
                                    }
                                }
                            }
                        }
                        oraDB.disconnect();
                    }
                    catch (Exception ex)
                    {
                        AddMessage(ex.Message);
                    }
                }
                #endregion
                #region 锁机
                if (!CardLockFlag)
                {
                    if (LampColor != 1)
                    {
                        if (timetick++ > 15 * 60)
                        {
                            Fx5u_2.SetM("M2606", true);
                            CardLockFlag = true;
                            CardLockTime = DateTime.Now;
                            AddMessage("机台锁定!");
                            timetick = 0;
                        }
                    }
                    else
                    {
                        timetick = 0;
                    }
                }
                else
                {
                    timetick = 0;
                }
                #endregion
            }
        }
        async void UpdateUI()
        {
            while (true)
            {
                await Task.Delay(200);

                #region 更新界面
                if (Fx5u.Connect)
                {
                    EllipsePLCState.Fill = Brushes.Green;
                }
                else
                {
                    EllipsePLCState.Fill = Brushes.Red;
                }
                if (Fx5u_2.Connect)
                {
                    EllipsePLCState2.Fill = Brushes.Green;
                }
                else
                {
                    EllipsePLCState2.Fill = Brushes.Red;
                }
                CycleText.Text = SWms.ToString() + " ms";
                #endregion
                #region 换班
                if (LastBanci != GetBanci())
                {
                    LastBanci = GetBanci();
                    Inifile.INIWriteValue(iniParameterPath, "Summary", "LastBanci", LastBanci);
                    LampGreenElapse = 0;
                    Inifile.INIWriteValue(iniParameterPath, "BigData", "LampGreenElapse", LampGreenElapse.ToString());
                    LampGreenFlickerElapse = 0;
                    Inifile.INIWriteValue(iniParameterPath, "BigData", "LampGreenFlickerElapse", LampGreenFlickerElapse.ToString());
                    LampYellowElapse = 0;
                    Inifile.INIWriteValue(iniParameterPath, "BigData", "LampYellowElapse", LampYellowElapse.ToString());
                    LampYellowFlickerElapse = 0;
                    Inifile.INIWriteValue(iniParameterPath, "BigData", "LampYellowFlickerElapse", LampYellowFlickerElapse.ToString());
                    LampRedElapse = 0;
                    Inifile.INIWriteValue(iniParameterPath, "BigData", "LampRedElapse", LampRedElapse.ToString());
                    await Task.Run(() =>
                    {
                        Mysql mysql = new Mysql();
                        try
                        {
                            int _result = -999;
                            if (mysql.Connect())
                            {
                                string stm = string.Format("INSERT INTO HA_F4_LIGHT (PM,LIGHT_ID,MACID,CLASS,LIGHT,SDATE,STIME,ALARM,TIME_1,TIME_2,TIME_3,TIME_4,TIME_5,GROUP1,TRACK,WORKSTATION) VALUES ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','0','0','0','0','0','{8}','{9}','{10}')"
                                                           , _PM, _LIGHT_ID, _MACID, GetBanci(), LampColor.ToString(), DateTime.Now.ToString("yyyyMMdd"), DateTime.Now.ToString("HHmmss"), "NA", _GROUP1, _TRACK, _WORKSTATION);
                                _result = mysql.executeQuery(stm);
                            }
                            this.Dispatcher.Invoke(new Action(() =>
                            {
                                AddMessage("插入数据库灯信号" + _result.ToString());
                            }));
                        }
                        catch (Exception ex)
                        {
                            this.Dispatcher.Invoke(new Action(() =>
                            {
                                AddMessage(ex.Message);
                            }));
                        }
                        finally
                        {
                            mysql.DisConnect();
                        }
                    });

                    Fx5u_2.SetM("M2606", true);
                    CardLockFlag = true;
                    CardLockTime = DateTime.Now;
                    AddMessage("机台锁定!");

                    AddMessage(LastBanci + " 换班数据清零");
                }
                #endregion
            }
        }