我现在做一个串口编程项目,思路如下:程序一启动则启动两个异步操作,由于串口同一时刻只能一个线程往里面写入东西,所以用到了一个全局变量IsAvailable,来标识当前串口是否空闲,现在就是在读取这个参数时有冲突,导致两个任务同时在操作,具体代码如下:1.程序开启时
/// <summary>
        /// 启动服务程序 
        /// </summary>
private void StartServer()
        {
            // 获取串口号列表
           cdts = new BLLM_Cdt().GetModelList(string.Empty);
            IList<string> comms = new List<string>();
            foreach (M_Cdt model in cdts)
            {
                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;                NewTaskDelegate pInitTime = new NewTaskDelegate(InitTime);
                IAsyncResult pInitTimeResult = pInitTime.BeginInvoke(pCI, null, null);                NewTaskDelegate pSetOpenTime = new NewTaskDelegate(SetOpenTime);
                IAsyncResult pSetOpenTimeResult = pSetOpenTime.BeginInvoke(pCI, null, null);            }
            
            #endregion
        }=======================================InitTime方法体=========================================================       /// <summary>
        /// 
        /// </summary>
        /// <param name="details"></param>
        void InitTime(Task pCI)
        {
            #region            if (pCI != null)
            {
                while (bStart)
                {
                    if (pCI.PortNum != null)
                    {
                        // 等待通道可利用
                        while (!pCI.IsAvailable)
                        {
                            Thread.Sleep(1000 * Config.SendInterval);
                        }
                        pCI.IsAvailable = false;                        // 执行其他方法内容
                                                 pCI.IsAvailable = true;
                    }
                    Thread.Sleep(1000 * Config.InitReadPlanInterVal);
                }
            }            #endregion
        }==============================SetOpenTime方法体========================================================        /// <summary>
        /// 设置定时时间
        /// </summary>
        void SetOpenTime(Task pCI)
        {
            #region            if (pCI != null)
            {
                while (bStart)
                {
                    if (pCI.PortNum != null)
                    {
                        // 等待通道可利用
                        while (!pCI.IsAvailable)
                        {
                            Thread.Sleep(1000 * Config.SendInterval);
                        }
                        pCI.IsAvailable = false;
                        
                       // 执行其他方法内容
                                                 pCI.IsAvailable = true;
                    }
                    Thread.Sleep(1000 * Config.InitControlPlanInterVal);
                }
            }            #endregion
        }
==================================Task结构体========================================================
/// <summary>
    /// 抄表任务
    /// </summary>
    public class Task
    {
        /// <summary>
        /// 串口号
        /// </summary>
        public int? PortNum=null;        /// <summary>
        /// 串口对象类
        /// </summary>
        public SerialPortUnit SPUnit;        /// <summary>
        /// 计划从表
        /// </summary>
        public IList<M_PlanDetail> PlanDetails;        /// <summary>
        /// 实时抄表计划
        /// </summary>
        public IList<M_RealTimePlan> M_RealTimePlans;        Mutex mutex = new Mutex();  
        object syncIsRunReal = new object();
        object syncIsAvailable = new object();
        bool isRunReal = false;
        public bool isAvailable = true;        /// <summary>
        /// 是否有实时抄表计划
        /// </summary>
        public bool IsRunReal
        {
            get
            {
                mutex.WaitOne();
                return isRunReal;
                mutex.ReleaseMutex();
            }
            set
            {
                mutex.WaitOne();
                isRunReal = value;
                mutex.ReleaseMutex();
            }
        }
        /// <summary>
        /// 广播校时时间:00:10:00
        /// 当校时完毕后修改广播校时时间为下一天的00:10:00
        /// </summary>
        public DateTime BroadCastTime = PublicBasis.DataTypeHelper.GetDateTime(DateTime.Now.ToString("yyyy-MM-dd 00:10:00"));        /// <summary>
        /// 下次读表时间,此时间是后台定时轮训时间
        /// 和抄表计划中的时间不同
        /// </summary>
        public DateTime NextTime = DateTime.Now;        /// <summary>
        /// 下次轮训报警时间
        /// </summary>
        public DateTime NextCheckWaringTime = DateTime.Now;        /// <summary>
        /// 下次初始化表具时间
        /// </summary>
        public DateTime NextInitTime = DateTime.Now;        /// <summary>
        /// 下次下发控制命令时间
        /// </summary>
        public DateTime NextSetOpenTime = DateTime.Now;
        /// <summary>
        /// 串口是否可用
        /// </summary>
        public bool IsAvailable
        {
            get
            {
                lock (syncIsAvailable)
                {
                    return isAvailable;
                }
            }
            set
            {
                lock (syncIsAvailable)
                {
                    isAvailable = value;
                }
            }
        }        /// <summary>
        /// 当前抄码对象
        /// </summary>
        public CurrPlanDetail CurrPlanDetail;        /// <summary>
        /// 当前实时抄码对象
        /// </summary>
        public CurrM_RealTimePlan currM_RealTimePlan;
        
        /// <summary>
        /// 初始化CurrPlanDetail
        /// </summary>
        /// <returns></returns>
        public CurrPlanDetail InitCurrPlanDetail(M_PlanDetail model)
        {
            CurrPlanDetail cpd = new CurrPlanDetail();
            PublicBasis.DataTypeHelper.Clone(cpd.planDetail, model);
            return cpd;
        }        /// <summary>
        /// 初始化CurrM_RealTimePlan
        /// </summary>
        /// <returns></returns>
        public CurrM_RealTimePlan InitCurrM_RealTimePlan(M_RealTimePlan model)
        {
            CurrM_RealTimePlan cpd = new CurrM_RealTimePlan();
            PublicBasis.DataTypeHelper.Clone(cpd.M_RealTimePlan, model);
            return cpd;
        }        /// <summary>
        /// 
        /// </summary>
        public List<M_PlanDetail> details;        public List<M_ControlPlanDetail> M_ControlPlanDetails;
    }现在两个方法经过测试,都有可能同时到达红色的部分,导致程序打架,请问如何控制可以解决该问题。
 // 等待通道可利用
                        while (!pCI.IsAvailable)
                        {
                            Thread.Sleep(1000 * Config.SendInterval);
                        }
                        pCI.IsAvailable = false;