日期:2014-05-18  浏览次数:20961 次

串口通信中的多线程问题
通过串口采集来自多个仪表的数据,协议是Modbus,仪表并接在RS485总线上,通过转接口连接到电脑USB接口
我现在用了一个计时器timer1,是System.Windows.Forms.Timer类型的,间隔一秒钟触发timer1_Tick函数
主要的代码是这样的:
C# code
private void timer1_Tick_1(object sender, EventArgs e)
        {
            try
            {
                System.Threading.Thread timerThread = new System.Threading.Thread(new System.Threading.ThreadStart(TimerMethod));
                    timerThread.Start();
                //周期性将临时数据存入历史数据库
            }
            catch (Exception exp)
            {
                timer1.Stop();
            }
        }
public void TimerMethod()
        {
            try
            {
                //清除临时数据
                using (SerialPort port = new SerialPort())
                {
                    //设置串口 
                    port.Open();
                    //从串口读数据
                    port.Close();
                            
                    if (con.State == ConnectionState.Open)
                    {
                        //将实时数据写入数据库
                        //***********显示实时数值                           
                        // ************刷新控件状态
                        //************判断是否报警
                       }                    
                }
            }
            catch (Exception exp)
            {
                timer1.Stop();
                System.Threading.Thread.CurrentThread.Abort();
            }
        }

在运行了一小段时间之后就会出现“对COM1的访问被拒绝”这样的错误,但是有时候又会一直运行下去很长时间才出错,我是第一次尝试写多线程的代码,希望有朋友帮我看一下我这样的方式是否可行,另外帮我分析下出现这个错误的可能原因是什么。
PS:因为TimerMethod代码太长所以只贴了说明文字,如果需要我选取详细的代码再贴上来

------解决方案--------------------
SerialPort是一种临界资源,就好像有一个座位一次只能坐一个人一样,坐多了就会出问题。

你上面的代码在多线程里面打开SerialPort,偶然可能会正好出现两个线程同时去打开COM1,或者一个已经打开了COM1,而另一个也企图去打开。

解决这个问题,可以将SerialPort做一次封装,内部使用单例模式。