其中 a 就是那个委托的对象。我断点调试了下 i的数据没问题 一直自加(1,2,3,4,5,6,7,8,9,1o.........) 但是就是显示的不对

解决方案 »

  1.   

    你写如下代码:
    for(int i=0;i<10000000;i++)
    {
    this.Invoke(a,i);
    }
    我不信你能看清每一个变化
    2个数据间隔时间太短,一次跳2个数,那不是太正常了
      

  2.   

    要么你别用rtb_Test.Text = (i).ToString();
    而改用rtb_Test.Text += (i).ToString()+" ";
    再看结果,看到底是没变,还是变的太快没看见
      

  3.   

    这个问题类似多线程共享变量使用冲突的问题。
    为证明问题。可以在i=i+i下面使用console.write(i.tostring);不要设置断点调试,输出i的值如果确实是这个问题。
    你可以用lock来解决。
      

  4.   

    接收几次跟发送几次没有任何关系
    你只发送一次,但是可能事件会执行2次,因为你使用的异步接收,不能确定回调函数到底什么时候执行
    比如设备给你发送10个字节,有可能接收到第1个字节它就执行了一次,也有可能先接收了9个再执行,也有可能一次性接收到,这都没准串口通信本身就不是像TCP和UDP那样有"包"的概念,所以程序也不可能自动给你判断每一次的数据是否完整,数据的完整性需要你自己做好协议去验证
      

  5.   

    TCP和UDP在互联网中应用时也会发生"粘包","分包"的现象
    何况你是串口,如果你发送的太快,很可能一次接收到设备的2次返回值,或者设备一次返回的数据你需要多次才能接收到
    所以你应该先将接收到的数据放到缓冲区里,比如就是一个List<byte>,每次接收完判断一下长度,如果不足先不处理,等待下一次接收完再次判断
      

  6.   


    串口DataReceived事件的触发不是你一秒钟发送一次就只触发一次的,还跟接收的字节数有关,你虽然是一秒一发,但是你一次发送多少字节的内容呢,从显示的内容看,一次发送的内容触发了3次DataReceived事件,就是1秒钟实际上触发了三次。
      

  7.   

    看了大家的解答 问题找了! 果然是一秒发一次数据,但是可能是分2或者3次接收。eg:我现在测试是2秒发16字节,接收到的是字节大部分是分开的 如: 16 ;10 6 ;6 5 5 ;3 13 ;4 12 ;4 12 ;3 13 ;3 13; 4 12; 3 13 ;5 11 ;4 12; 3 13 ;5 11 5。很少有一次能接16个字节的。怎么能同步接收呢?就是一次数据发完了再接收!在硬件上的中断就是一次收一个字节有个计时器 超过一定时间没数据 就算一包。那我怎么处理啊 因为数据长度不定 不能按长度处理。我的思路是开个定时器或者线程500ms处理一次数据。处理完把数组清了 。因为是1秒1发 500ms足够接收完数据。但是我感觉这种方法不好 有没有什么更好的方法。
      

  8.   

    看了大家的解答 问题找了! 果然是一秒发一次数据,但是可能是分2或者3次接收。eg:我现在测试是2秒发16字节,接收到的是字节大部分是分开的 如: 16 ;10 6 ;6 5 5 ;3 13 ;4 12 ;4 12 ;3 13 ;3 13; 4 12; 3 13 ;5 11 ;4 12; 3 13 ;5 11 5。很少有一次能接16个字节的。怎么能同步接收呢?就是一次数据发完了再接收!在硬件上的中断就是一次收一个字节有个计时器 超过一定时间没数据 就算一包。那我怎么处理啊 因为数据长度不定 不能按长度处理。我的思路是开个定时器或者线程500ms处理一次数据。处理完把数组清了 。因为是1秒1发 500ms足够接收完数据。但是我感觉这种方法不好 有没有什么更好的方法。
    首先你要确定下位机(硬件)与上位机记性收发数据时,并不严格按照逻辑意义的“包”进行
    即:
    1.一个包可能分多个帧发出或接收。
    2.一个帧里面有可能含有多个包的数据比如,逻辑的包的数据是 第一个包3A 00 0c 03 05 3F  第二包 3A 00 0f 04 06 cc
    那么接收到的帧有可能是 3A 00;0c 03 05 3f 3A;00 0f 04 06 cc针对上述情况,需要定义通讯协议,按照具体的场景可以定义不同复杂度的协议简单的情况,直接协商一个包结束字节(该字节不会在数据中出现)
    一般的情况下,建议使用类似状态机协议,比如定义一包的数据 包头是啥,第二个字节是数据长度,后面跟上数据,最后加上校验码更复杂的不建议重复造轮子,可以借鉴RFID、TCP等等的数据协议
      

  9.   

    看了大家的解答 问题找了! 果然是一秒发一次数据,但是可能是分2或者3次接收。eg:我现在测试是2秒发16字节,接收到的是字节大部分是分开的 如: 16 ;10 6 ;6 5 5 ;3 13 ;4 12 ;4 12 ;3 13 ;3 13; 4 12; 3 13 ;5 11 ;4 12; 3 13 ;5 11 5。很少有一次能接16个字节的。怎么能同步接收呢?就是一次数据发完了再接收!在硬件上的中断就是一次收一个字节有个计时器 超过一定时间没数据 就算一包。那我怎么处理啊 因为数据长度不定 不能按长度处理。我的思路是开个定时器或者线程500ms处理一次数据。处理完把数组清了 。因为是1秒1发 500ms足够接收完数据。但是我感觉这种方法不好 有没有什么更好的方法。
    如果你非要这样,就给每个串口开个线程,用while(true)同步接收,
    否则你现在是异步接收,系统接收到数据就会自动调用回调函数
      

  10.   

    这里有我写的例子
    其中API方式就是同步接收的
    当然你也可以用SerialPort同步接收
      

  11.   

    是不是大家接收的时候都这样啊 ,今天用监视软件测试了一下别人的程序,为什么别人的是偶尔出现呢 我这个总是这样 测试的java写的!
      

  12.   

    多线程中不能胡乱共享外部变量。大致来说,流程应该这样            if (rtb_Test.InvokeRequired)
                 {
                     int j;
                     lock(lockFlagObject)
                     {
                         i = i + 1;
                         j = i;
                     }
                     this.Invoke(a,j);
                 }
                 else
                 {
                     rtb_Test.Text = Builder.ToString();
                 }
    其中最关键的,是要传送互不共享的j变量,而不是i。
      

  13.   

    当然你说的“winform 使用DataReceived ”设置为仅仅在主线程触发的,那么不用考虑它是在子线程中运行问题。但是这样,就不可能出现“1 ,3,,6, 9 , 12”的问题,而且你为什么要写 this.Invoke 而不直接调用a方法呢?到底,你得 DataReceived 是在主线程触发的,还是在不同的子线程触发的,这需要你自己回答这个问题。
      

  14.   


    仔细看回复,问题解决了。跨线程调用需要invoke。
      

  15.   

    先MARK,我也碰到这个问题,我是serialPort.DataReceived += new SerialDataReceivedEventHandler(ReceiveData)就是这个样子,如果接到的是'01 02 03'那么就基本会先接到'01'然后再'02 03',我觉得问题就在这个触发上面。