由于读取串口操作是在控件中执行,因此一旦运行读取操作,主线程就会“卡死”,请问如何把一个读取串口操作的自定义控件放入线程中?

解决方案 »

  1.   

            delegate void ProcessDelegate(string sPortData);   //代理(同步显示串口数据)
            private ProcessDelegate process;     /// <summary>
            /// 设置controlLED显示数据
            /// </summary>
            /// <param name="sNum">要显示的数字</param>
            private void setLED(string sPortData)
            {
                this.iLEDnum = int.Parse(sTrData); 
            }
            /// <summary>
            /// 串口数据激活事件   ReceivedBytesThreshold = 12 每12字节激活一次
            /// </summary>
            private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                try
                {
                    InputData = this.serialPort1.ReadTo("=");
                    if (InputData != String.Empty && InputData.Length == 8)
                    {                    
                        process(InputData);
                    }
                }
                catch
                { }
            }我使用的是代理!!但是好像没有作用!!
      

  2.   

    process = new ProcessDelegate(setLED);
      

  3.   

            private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) 
            { 
                  Thread tReceive=new Thread(new ThreadStart(ReceiveData));
                  tReceive.Start();
            }       private void ReceiveData()
          {
            //这里面放读操作代码
                 try 
                { 
                    InputData = this.serialPort1.ReadTo("="); 
                    if (InputData != String.Empty && InputData.Length == 8) 
                    {                     
                        process(InputData); 
                    } 
                } 
                catch 
                { } 
           }
      

  4.   

    DataReceived 是每12个字节自动执行一次!!会不会产生线程太多了? 如何最优化执行呢?
      

  5.   

    先谢谢 dancingbit 的帮助! 我对于线程方面的操作不太了解!!我的思路是这样的!! DataReceived 是每12个字节自动执行一次! 在自动触发时,开启线程读取数值,然后启动委托更新界面控件数值,更新完毕,线程挂起运行!那么如何做呢?我测试使用在load时启动线程:
            private void LED_Load(object sender, EventArgs e)
            {
                tReceive = new Thread(new ThreadStart(ReceiveData));
                tReceive.Start();
            }然后在
            private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)  
            {  
                if(线程运行状态)
                {
                    tReceive.Start();  
                }
                else
                {
                    tReceive.Suspend();
                }
            }但是好像不行!!还有线程运行状态如何判断?IsAlive吗?
      

  6.   

    IsAvlive只是判断该线程是否存活,判断状态需使用ThreadState
    挂起后恢复也不是使用Start,而是使用Resume
      

  7.   

    tReceive.ThreadState == ThreadState.Running ??
      

  8.   

    if(tReceive.ThreadState==ThreadState.Suspended)
       tReceive.Resume();至于挂起的时机,应在读完当前的数据之后还是那个意见,要么就别挂起了,根据某个标志变量判断当前有没有数据可读,没有数据就不断地Thread.Sleep如下形式:while(true)
    {
       if(终止变量为真)
         break;
       if(有数据可读)
          {//读数据
          }
        else
          Thread.Sleep(300);
    }
      

  9.   

    9600 波特的!! 一前在 1200 低下测试没有卡死 可能就是数据处理占用了大量的CPU!
      

  10.   

    要不您还是先用一下Windows中的超级终端测试一下吧.
      

  11.   

    注意主要的配置1. data bit 
    2. port
    3. parity
    4. stop bits
    5. max speed
    6. flow 这些都是串口通讯的参数,如果配制有问题,会卡死的。
      

  12.   

    kindyaloner 这些设置都是按照设备说明书配置的!!
      

  13.   

    www.codeproject.com
    上有专门介绍线程的例子,
    感觉你可以用线程同步去做,没必要把线程挂起,
      

  14.   

    没必要把它放到线程里,是在vs2005下,线程不允许访问主界面代码。用代理就可以了
      if (m_list.InvokeRequired)
                {
                    m_list.Invoke(new EventHandler(delegate
                    {
                        m_list.Text = str + "\r\n" + m_list.Text;
                    }
                    ));
                }
                else
                {
                    m_list.Text = str + "\r\n" + m_list.Text;
                }
    m_list是你要显示串口来的数据。
      

  15.   

    jiayp004 谢谢你的回复!!不过我的控件是数据显示在控件内的LED中!!不用单独在主界面刷新显示!!为了防止串口数据显示控件读取串口数据时引起主界面假死,所以想要实现把串口数据显示控件放入线程运行!
      

  16.   

    串口接收数据最好Sleep下,减轻CPU负担
      

  17.   

    使用Sleep容易造成主线程假死!!