我最近开发一个form程序,使用了serialPort控件,使用的是DataReceive事件的方式接收串口信息,但是现在我遇到了一个问题。如下:我按下主界面中的“联机”按钮,在其函数中我往串口发送一个联机信息,同时查询某一个标志位是否置1.比如
private int send_ok = -1;
 private void toolStripButton_联机_Click(object sender, EventArgs e)
{
    SendCommand((byte)0x1B, 12,ref send_ok );
}
 private Error_Information SendCommand(byte Add, int Number,ref int sd_ok)
         {
             sd_ok = -1;
            double spansecond = 0;
            double m_waitrime = 50;
            int send_count = 0;
            do
            {
                   if (SendCom(Add,Number))
                   {
                       TimeSpan span = new TimeSpan();
                       DateTime start_time = DateTime.Now;                       while ((spansecond <= m_waitrime) && (send_ok == -1))
                       {
                           span = DateTime.Now - start_time;
                           spansecond = span.TotalMilliseconds;
                       }
                       spansecond = 0;
                   }
                   else
                   {
                       MessageBox.Show("串口数据传输错误", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                       return Error_Information .RCC_ERROR_FAILDSEND;
                   }
                   if (sd_ok >= 0)
                   {
                       break;
                   }
                   send_count++;
             } while (send_count < 1);
             if (sd_ok < 0)
               // 发送出错
            {
                   MessageBox.Show("发送命令超过最大的次数", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                   return Error_Information .RCC_ERROR_FAILDSEND;
            }
           return Error_Information.RCC_ERROR_SUCCESS;
       }
       //将数据发送出去
        public bool SendCom(byte Add, int Number)
       {
             transmitCommand[0] = (byte)0x01;
             transmitCommand[1] = (byte)0xFF;
             transmitCommand[2] = Add;
             transmitCommand[11] = (byte)( transmitCommand[0] + transmitCommand[1] + transmitCommand[2] + transmitCommand[3] +
                                           transmitCommand[4] + transmitCommand[5] + transmitCommand[6] + transmitCommand[7] +
                                           transmitCommand[8] + transmitCommand[9] + transmitCommand[10]);
            
          
           try
           {
               serialPort1.Write(transmitCommand, 0, Number);
               while(send_ok == -1);           }
           catch
           {
               return false;
           }
           return true;
       }
其中send_ok在DataReceive的事件程序中置1,但是现在的现象是一联机就死机了,停在了while(send_ok == -1);,我的问题是:DataReceive不是辅助线程吗?为什么不能把send_ok = 1;呢?我确定下位机肯定回传了联机成功的信息。请高手指教!

解决方案 »

  1.   

    http://blog.csdn.net/JustLovePro/archive/2008/12/15/3523348.aspx
     //是否允许跨线程访问 
      // CheckForIllegalCrossThreadCalls = false;       
      

  2.   

    http://blog.csdn.net/JustLovePro/archive/2008/12/09/3485106.aspx
      

  3.   

    看了下代码,感觉代码有问题
    程序中除了send_ok或sd_ok赋-1的地方,没看见哪个地方对它赋另外的值
    所以while(send_ok == -1); 就一直死循环了
      

  4.   

    呵呵,不好意思
    还有一部分代码,我没贴出来,send_ok = 1;在private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)中,代码太多,没贴出来。
      

  5.   

    刚看过楼上推荐的网页,他们是采用委托机制实现的对主界面的控件操作,这是.net2.0的特性吧,如果需要使用委托来解决问题,那是否可以这样理解,由于我的send_ok是全局变量,也是主界面的变量,DataReceive事件程序是不能够直接访问send_ok变量的?其实实践证明是可以的,只是目前的现象是SendCom方法在运行的时候会死在while(send_ok == -1);而程序不会进到DataReceive中,即便是串口中有数据。也就是说,我在一直查询send_ok状态的时候,DataReceive这个辅助线程好像不起作用。而我原先理解的是,主界面和DataReceive应该不是在同一个线程里面啊。唉,我越说自己越糊涂了。
      

  6.   

      while ((spansecond <= m_waitrime) && (send_ok == -1)) 
                          { 
                              span = DateTime.Now - start_time; 
                              spansecond = span.TotalMilliseconds; 
                          } 
    在这里面增加Thread.sleep(16)可能会好些while ((spansecond <= m_waitrime) && (send_ok == -1)) 
                          { 
                              span = DateTime.Now - start_time; 
                              spansecond = span.TotalMilliseconds; 
    Thread.sleep(16)
                          }
      

  7.   

    Thread.sleep(16);主线程在休眠的时候,datareceive还有效吗?
      

  8.   

    一种是:
    while(send_ok == -1);  
    改为:while(send_ok == -1)
               Thread.Sleep(5);  
    试试。建议不要采用这种方式。
    SendCmd后立即返回,同时采用一个线程来接受数据,并在一定的时间内进行判断,并使用代理返回一个联机是否成功的标识,然后在做。
      

  9.   

    试了几次你们提供的方法,还是不行。后来想既然两个线程,干脆使用属性的方式访问send_ok,问题解决。感谢大家的帮助!
      

  10.   

    请参考http://topic.csdn.net/u/20081220/12/db6b9150-91b7-432b-820e-85c7e6265787.html