我的问题是要把多块表的抄表时间发到单片机上去,现在功能实现,比如我写入一个表具的抄表时间,成功后里面会反馈消息,我根据消息好做下一步处理,现在问题出在这块 if (pCI != null&&model.Comm.ToString().Equals(pCI.PortNum.ToString()))
                {
                    Tools.ShowContentHint(string.Format("采集串口 " + pCI.PortNum.ToString() + " 开始初始化抄表 CDT编号:{0} 安装序号{1}",model.CdtNum,model.SerialNo));
                    // 等待通道可利用
                    while (!pCI.IsAvailable)
                    {
                        Thread.Sleep(1000 * Config.SendInterval);
                    }
                    pCI.IsAvailable = false;
                    pCI.SPUnit.WaitEvent.Reset();
                    pCI.SPUnit.SendData(InstructionSet.GetInitReadTimeCommandCmd(cdt, meter, model));
                    if (!pCI.SPUnit.WaitEvent.WaitOne(6000, false))
                    {
                        #region 
// 我的想法是发送后让线程等待6S,如果6S后还没接收完或没反馈就当超时处理,跟踪是有反馈的,就是进不来。
                        // 我修改为WaitOne(-1, false)为无限等待也不行,主要对这WaitOne不理解,查了资料还不明白,所以请教大侠                        string pReturnStr = InstructionSet.ByteToHexString(pCI.SPUnit.pbReceiveArr, true);
                       
                        #endregion
                    }
                    else
                    {
                        Tools.ShowContentHint(string.Format("采集串口 " + pCI.PortNum.ToString() + " CDT编号:{0} 安装序号{1} 无应答反馈", model.CdtNum, model.SerialNo));
                    }
                    pCI.IsAvailable = true;
                }                #endregion
            }
            pCI.SPUnit.CloseComm();
        } ============================================================= 调用部分=================================================================
 /// <summary>
        /// 发送抄表配置信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendPlan_Click(object sender, EventArgs e)
        {
            #region            if (this.dgvPlan.CurrentRow != null)
            {
                int planId = PublicBasis.DataTypeHelper.GetInt(this.dgvPlan.CurrentRow.Cells["CPlanID"].Value);
                List<M_PlanDetail> details = new SC.SSH.BLL.BLLM_PlanDetail().GetModelList(string.Format("PlanId={0} and IsSend=0", planId));                IList<string> comms = new List<string>();
                foreach (SC.SSH.Model.M_PlanDetail model in details)
                {
                    if (!comms.Contains(model.Comm.ToString()))
                    {
                        comms.Add(model.Comm.ToString());
                    }
                }                // 初始化串口实例
                foreach (string comm in comms)
                {
                    SerialPortUnit serialPort = new SerialPortUnit("COM" + comm);
                    Task pCI = new Task();
                    pCI.PortNum = DataTypeHelper.GetInt(comm);
                    pCI.SPUnit = serialPort;
                    pCI.details = details;                    // 异步初始化抄表时间
                    NewTaskDelegate pInitTime = new NewTaskDelegate(InitTime);
                    IAsyncResult pInitTimeResult = pInitTime.BeginInvoke(pCI, null, null);
                }
            }
            else
            {
                MessageBox.Show("请选择需要发送的计划");
            }            #endregion
        }====================================================================这是我封装的一个任务类===================================================
  /// <summary>
    /// 抄表任务
    /// </summary>
    public class Task
    {
        /// <summary>
        /// 串口号
        /// </summary>
        public int? PortNum=null;        /// <summary>
        /// 串口对象类
        /// </summary>
        public SerialPortUnit SPUnit;        /// <summary>
        /// 计划从表
        /// </summary>
        public IList<M_PlanDetail> PlanDetails;        /// <summary>
        /// 广播校时时间:00:10:00
        /// 当校时完毕后修改广播校时时间为下一天的00:10:00
        /// </summary>
        public DateTime BroadCastTime = PublicBasis.DataTypeHelper.GetDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:10:00")).AddDays(1);        /// <summary>
        /// 下次读表时间,此时间是后台定时轮训时间
        /// 和抄表计划中的时间不同
        /// </summary>
        public DateTime NextTime = DateTime.Now;        /// <summary>
        /// 下次轮训报警时间
        /// </summary>
        public DateTime NextCheckWaringTime = DateTime.Now;        /// <summary>
        /// 串口是否可用
        /// </summary>
        public bool IsAvailable = true;        /// <summary>
        /// 当前抄码对象
        /// </summary>
        public CurrPlanDetail CurrPlanDetail;
        
        /// <summary>
        /// 初始化CurrPlanDetail
        /// </summary>
        /// <returns></returns>
        public CurrPlanDetail InitCurrPlanDetail(M_PlanDetail model)
        {
            CurrPlanDetail cpd = new CurrPlanDetail();
            PublicBasis.DataTypeHelper.Clone(cpd.planDetail, model);
            return cpd;
        }        /// <summary>
        /// 
        /// </summary>
        public List<M_PlanDetail> details;        public List<M_ControlPlanDetail> M_ControlPlanDetails;
    }
}

解决方案 »

  1.   

    =================================================================串口操作类=======================================================================
     public class SerialPortUnit
        {        #region 公共事件        public delegate void Func(params object[] values);        public delegate void DataArrivedHandler(byte[] dataReceived, int sizeReceived, string portName);        public event DataArrivedHandler DataArrived;        #endregion        #region 私有属性        private SerialPort sp = new SerialPort();                               //创建一个串口类        public AutoResetEvent WaitEvent = new AutoResetEvent(false);           //创建一个线程事件        private int _ReadTimeout;                                               //读数据超时(从开始收数据到所有数据接收完用的时间)        private string _ErrMsg;                                                 //错误信息        private DateTime lastTimeing = PublicBasis.DataTypeHelper.GetDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:10:00"));        #endregion        #region 公共接口        /// <summary>
            /// 错误信息
            /// </summary>
            public string ErrMsg
            {
                get
                {
                    return _ErrMsg;
                }
            }        /// <summary>
            /// 上次校时时间
            /// </summary>
            public DateTime LastTiming
            {
                get
                {
                    return lastTimeing;
                }
                set
                {
                    lastTimeing = value;
                }
            }        #endregion        #region 静态属性        /// <summary>
            /// 串口号:COM1
            /// </summary>
            public string PortName = "COM1";        /// <summary>
            /// 波特率:9600
            /// </summary>
            public int BaudRate = 4800;        /// <summary>
            /// 停止位:1
            /// </summary>
            public int StopBit = 1;        /// <summary>
            /// 数据位:8
            /// </summary>
            public int DataBit = 8;        /// <summary>
            /// 校验位:0
            /// </summary>
            public int CheckBit = 0;        #endregion        #region 发送、接收数据属性        private byte[] pbSendArr;                                               //待发送数据                                                         private int pbSendArrLength;                                            //待发送数组长度        //public string pstrSend;                                               //转化为字符串的待发送数据        public byte[] pbReceiveArr;                                            //接收数据数组        private int pbReceiveArrLength;                                         //接收数据的长度        public string pStrReceive;                                              //接收到得数据字符串,已经转换成16进制的字符串        #endregion
            /// <summary>
            /// 清空错误信息
            /// </summary>
            private void ClearError()
            {
                _ErrMsg = string.Empty;
            }        /// <summary>
            /// 
            /// </summary>
            /// <param name="value"></param>
            private void SetError(string value)
            {
                _ErrMsg = value;
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="seconds"></param>
            public void Sleep(float seconds)
            {
                Application.DoEvents();
                Thread.Sleep((int)(seconds * 1000));
                Application.DoEvents();
            }        /// <summary>
            /// 构造函数
            /// </summary>
            public SerialPortUnit(string portName)
            {
                #region            PortName = portName;
                sp.PortName = PortName;
                sp.BaudRate = BaudRate;
                sp.Parity = (System.IO.Ports.Parity)CheckBit;
                sp.DataBits = DataBit;
                sp.StopBits = (System.IO.Ports.StopBits)StopBit;
                sp.Handshake = System.IO.Ports.Handshake.None;
                this.sp.ReadBufferSize = 4096;
                this.sp.WriteBufferSize = 4096;
                this.pbSendArr = new byte[this.sp.WriteBufferSize];
                this.pbReceiveArr = new byte[this.sp.ReadBufferSize];
                this._ReadTimeout = 3000;
                this.sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);            #endregion
            }
            /// <summary>
            /// 
            /// </summary>
            public void InitCom()
            {
                #region            sp.PortName = PortName;
                sp.BaudRate = BaudRate;
                sp.Parity = (System.IO.Ports.Parity)CheckBit;
                sp.DataBits = DataBit;
                sp.StopBits = (System.IO.Ports.StopBits)StopBit;
                sp.Handshake = System.IO.Ports.Handshake.None;            #endregion
            }        bool bDataReceived = true;        /// <summary>
            /// 串口接收数据事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                #region            //Sleep(2f);
                bDataReceived = true;
                ClearInBuffer();
                bool result = ReceiveData();
                WaitEvent.Set();            #endregion
            }        /// <summary>
            /// 自动接收数据
            /// </summary>
            /// <returns></returns>
            private bool ReceiveData()
            {
                #region            int iLen = 0;
                try
                {                while (bDataReceived)
                    {
                        bDataReceived = false;
                        ClearError();                    // 取发送过来的数据长度
                        iLen = sp.BytesToRead;
                        if (iLen > 0)
                        {
                            pbReceiveArr = new byte[iLen];
                            sp.Read(pbReceiveArr, 0, iLen);
                            bDataReceived = true;
                        }                    Sleep(0f);
                        if (bDataReceived && DataArrived != null)
                        {
                            DataArrived(pbReceiveArr, iLen, PortName);
                            bDataReceived = false;
                        }
                    }
                }
                catch (Exception e)
                {
                    SetError(e.Message);
                    return false;
                }
                return true;            #endregion
            }        #region 打开、关闭串口        /// <summary>
            /// 打开串口
            /// </summary>
            /// <returns></returns>
            public bool OpenComm()
            {
                #region            ClearError();            try
                {                if (!sp.IsOpen)
                    {                    InitCom();                    sp.Open();                }            }            catch (Exception e)
                {                SetError(e.Message);                return false;            }            return true;            #endregion
            }        /// <summary>
            /// 关闭串口
            /// </summary>
            public void CloseComm()
            {
                #region            try
                {                if (sp.IsOpen)
                    {
                        sp.DataReceived -= new SerialDataReceivedEventHandler(sp_DataReceived);
                        sp.Close();                }            }            catch
                {                return;            }            #endregion
            }        #endregion        /// <summary>
            ///发送数据
            ///在发送前先清空发送和接收缓冲区
            /// </summary>
            public bool SendData()
            {
                #region            OpenComm();            ClearError();            bool b = true;            try
                {                this.sp.DiscardInBuffer();                this.sp.DiscardOutBuffer();                // 2010-04-28
                    //Sleep(0.02f);                //this.sp.Write(pbSendArr, 0, pbSendArrLength);                for (int i = 0; i < pbSendArr.Length; i++)
                    {
                        this.sp.Write(pbSendArr, i, 1);
                        Sleep(0.01f);
                    }
                    b = true;            }            catch (Exception e)
                {                SetError(e.Message);                b = false;            }            return b;
                #endregion
            }        /// <summary>
            /// 
            /// </summary>
            /// <param name="datas"></param>
            /// <returns></returns>
            public bool SendData(byte[] datas)
            {
                #region            pbSendArr = datas;
                pbSendArrLength = datas.Length;
                return SendData();            #endregion
            }        /// <summary>
            /// 
            /// </summary>
            /// <param name="strSend"></param>
            /// <returns></returns>
            public bool SendData(string strSend)
            {
                #region            string s = " ";
                char[] sc = s.ToCharArray();
                string Endstr = strSend.Trim();            string[] str = Endstr.Split(sc);
                Byte[] send = new Byte[str.Length];
                for (int n = 0; n < str.Length; n++)
                {
                    send[n] = byte.Parse(str[n], System.Globalization.NumberStyles.HexNumber);
                }
                bool result = SendData(send);
                return result;            #endregion
            }        /// <summary>
            /// 清除接收数组内的内容
            /// </summary>
            private void ClearInBuffer()
            {
                #region            this.pbReceiveArrLength = 0;
                this.pStrReceive = string.Empty;            #endregion
            }
        }
    }