yuanshi3 发表于 2009-6-28 17:18:09

针对这个用doevents 在VB怎么解决啊

Private Sub Command20_Click()
    Dim Temp As String
    Dim buff_out7() As Byte
    ReDim buff_out7(8)
    Dim u As Long
    MSComm1.Settings = "9600,N,8,1"   ' 9600 波特,无奇偶校验,8 位数据,一个停止位。
    MSComm1.InputLen = 0            ' 当输入占用时,告诉控件读入整个缓冲区。
    buff_out7(0) = &HAA
    buff_out7(1) = &HAA
    buff_out7(2) = &HFF
    buff_out7(3) = &H1
    Open App.Path & "\2.txt" For Input As #2
      Line Input #2, Temp
    Close #2
    u = Val(Temp)
    If u > 0 And u < 65536 Then
    buff_out7(5) = u Mod 256
    buff_out7(4) = u \ 256
    buff_out7(6) = &H0
    buff_out7(7) = &H0
    buff_out7(8) = &HFF
      If MSComm1.PortOpen = False Then
          Label1.Caption = "您的串口现在是关闭状态,请先打开串口"
      Else
            MSComm1.Output = buff_out7
            Label1.Caption = ""
      End If
    End If
End Sub



针对这个用doevents 怎么解决啊 ?有的说用doevents 可以解决我VB无规律死机的问题 。就是不知道什么时候鼠标就不能操作了,没有一点规律可循。只能关闭VB的exe文件,再次打开,就回出现串口占用,唯一的办法就是重启电脑。

cqfeiyu 发表于 2009-6-28 18:55:15

这个里面没有要用到doevents的地方

Friendz 发表于 2009-6-28 21:13:45

在任务管理器中,关闭占用串口的程序试试。

再不然就用回调函数,不要让程序总在那儿等待。

general_dwf 发表于 2009-6-28 21:51:52

用到循环的地方,建议都加上doevents 使CPU不至于死等

yuanshi3 发表于 2009-6-28 22:29:43

回2楼 在任务管理器中中根本就删除不了 唯一的办法就是重启电脑 否则就提示串口占用 你说回调函数怎么个回调法 谢谢!
回【3楼】 general_dwf,但是我VB里面发送命令的地方都没有用到循环啊。就如上面的命令。感谢!

snoopyzz 发表于 2009-6-28 23:28:10

taskkill /f /t /pid xxx
xxx就是你进程的pid
必然能关上...
除非有双进程互锁...

yuanshi3 发表于 2009-6-29 10:18:36

不懂ls的“taskkill /f /t /pid xxx ”什么意思,能否具体说下

gdyaojie 发表于 2009-6-29 19:15:22

LZ发了这么多贴, 我的理解从你这块代码似乎看不到死机的原因, 你整个VB工程代码仔细检查过没有?

例如有没有用到定时器之类的?不定时假死有可能是别的地方引起的.

如果愿意, 可以把整个代码给我, 我帮你看看.

yuanshi3 发表于 2009-6-29 20:43:10

我也仔细检查过 单纯的往助手上发协议是很顺畅的 就是和下位机连接上后就有时候VB界面不好使了
用到了定时器,如下:
'定时器延时
Private Sub Timer1_Timer()
   Dim longth As Integer
    If Check1.Value = 1 Then
    intOutMode = 1
    Else
    intOutMode = 0
    End If
    strSendText = pl.Text + zkb.Text + sq.Text
    If intOutMode = 0 Then
      MSComm1.Output = strSendText
    Else
      longth = strHexToByteArray(strSendText, bytSendByte())
      If longth > 0 Then
            MSComm1.Output = bytSendByte
      End If
    End If
    If Label16.Caption <> CStr(Time) Then
      Label16.Caption = Time$
    End If
End Sub

gdyaojie 发表于 2009-6-29 21:08:24

你的定时器多长时间触发一次?

这段代码本身没看到循环, 用到一个自己写的函数:strHexToByteArray, 该函数代码没看到.   按理应该不会引起界面假死.除非你的定时器的时间定得太短, 在上一次的事件处理没结束的情况下再次触发,如果是这种情况, 你可以尝试在定时器代码的前面加上: Timer1.Enabled=False, 进入代码就关闭定时器, 在代码最后加上Timer1.Enabled=true,看看情况有没有改善.

yuanshi3 发表于 2009-6-30 10:32:30

我看了下 就是下面用了循环:

Function strHexToByteArray(strText As String, bytByte() As Byte) As Integer
   
    Dim HexData As Integer          '十六进制(二进制)数据字节对应值
    Dim hstr As String * 1          '高位字符
    Dim lstr As String * 1          '低位字符
    Dim HighHexData As Integer      '高位数值
    Dim LowHexData As Integer       '低位数值
    Dim HexDataLen As Integer       '字节数
    Dim StringLen As Integer      '字符串长度
    Dim Account As Integer          '计数
    Dim n As Integer
    'strText = ""                   '设初值
    HexDataLen = 0
    strHexToByteArray = 0
   
    StringLen = Len(strText)
    Account = StringLen \ 2
    ReDim bytByte(Account)
   
    For n = 1 To StringLen               'For...Next循环语句
   
      Do                                              '清除空格
            hstr = Mid(strText, n, 1)
            n = n + 1
            If (n - 1) > StringLen Then
                HexDataLen = HexDataLen - 1
               
                Exit For
            End If
      Loop While hstr = " "                   'DO...Loop While循环
      
      Do
            lstr = Mid(strText, n, 1)
            n = n + 1
            If (n - 1) > StringLen Then
                HexDataLen = HexDataLen - 1
               
                Exit For
            End If
      Loop While lstr = " "
      n = n - 1
      If n > StringLen Then
            HexDataLen = HexDataLen - 1
            Exit For
      End If
      
      HighHexData = ConvertHexChr(hstr)
      LowHexData = ConvertHexChr(lstr)
      
      If HighHexData = -1 Or LowHexData = -1 Then   '遇到非法字符中断转化
            HexDataLen = HexDataLen - 1
            
            Exit For
      Else
            
            HexData = HighHexData * 16 + LowHexData
            bytByte(HexDataLen) = HexData
            HexDataLen = HexDataLen + 1
            
            
      End If
                        
    Next n
   
    If HexDataLen > 0 Then                              '修正最后一次循环改变的数值
      HexDataLen = HexDataLen - 1
      ReDim Preserve bytByte(HexDataLen)
    Else
      ReDim Preserve bytByte(0)
    End If
   
    If StringLen = 0 Then                               '如果是空串,则不会进入循环体
      strHexToByteArray = 0
    Else
      strHexToByteArray = HexDataLen + 1
    End If
   
End Function

gdyaojie 发表于 2009-6-30 10:44:36

问题应该出在这个strHexToByteArray函数, 在

For n = 1 To StringLen
后面加上DoEvents

还有后面的DO循环的第一行都加上DoEvents, 应该可以解除界面死锁的问题.


如果想替换掉字符串中的空格,可以使用replace函数.


另外, 你这个循环需要优化, 外层的FOR循环, 里面的两个DO循环, 都是字符串的长度, 循环的总次数是长度的几次方.如果定时器间隔很短, 会重复进入, 会导致意料不到的事情发生.


还有, 看到ConvertHexChr这个函数, 根据LZ的代码风格, 估计这个函数的代码也会用到循环, 建议LZ对 strHexToByteArray 所涉及到的代码进行优化, 因为strHexToByteArray是定时器要用到的, 本身定时器就是一个大循环, 这种密集运算的循环会占用CPU资源不放, 建议LZ在必要的地方放置DOEvents语句.

yuanshi3 发表于 2009-6-30 11:13:28

恩 好的 你说的除了这样修改还怎么修改(就加了2个DoEvents ):
Function strHexToByteArray(strText As String, bytByte() As Byte) As Integer
   
    Dim HexData As Integer          '十六进制(二进制)数据字节对应值
    Dim hstr As String * 1          '高位字符
    Dim lstr As String * 1          '低位字符
    Dim HighHexData As Integer      '高位数值
    Dim LowHexData As Integer       '低位数值
    Dim HexDataLen As Integer       '字节数
    Dim StringLen As Integer      '字符串长度
    Dim Account As Integer          '计数
    Dim n As Integer
    'strText = ""                   '设初值
    HexDataLen = 0
    strHexToByteArray = 0
   
    StringLen = Len(strText)
    Account = StringLen \ 2
    ReDim bytByte(Account)
   
    For n = 1 To StringLen               'For...Next循环语句
      DoEvents
      Do                                              '清除空格
            hstr = Mid(strText, n, 1)
            n = n + 1
            If (n - 1) > StringLen Then
                HexDataLen = HexDataLen - 1
               
                Exit For
            End If
      Loop While hstr = " "                   'DO...Loop While循环
      DoEvents
      Do
            lstr = Mid(strText, n, 1)
            n = n + 1
            If (n - 1) > StringLen Then
                HexDataLen = HexDataLen - 1
               
                Exit For
            End If
      Loop While lstr = " "
      n = n - 1
      If n > StringLen Then
            HexDataLen = HexDataLen - 1
            Exit For
      End If
      
      HighHexData = ConvertHexChr(hstr)
      LowHexData = ConvertHexChr(lstr)
      
      If HighHexData = -1 Or LowHexData = -1 Then   '遇到非法字符中断转化
            HexDataLen = HexDataLen - 1
            
            Exit For
      Else
            
            HexData = HighHexData * 16 + LowHexData
            bytByte(HexDataLen) = HexData
            HexDataLen = HexDataLen + 1
            
            
      End If
                        
    Next n
   
    If HexDataLen > 0 Then                              '修正最后一次循环改变的数值
      HexDataLen = HexDataLen - 1
      ReDim Preserve bytByte(HexDataLen)
    Else
      ReDim Preserve bytByte(0)
    End If
   
    If StringLen = 0 Then                               '如果是空串,则不会进入循环体
      strHexToByteArray = 0
    Else
      strHexToByteArray = HexDataLen + 1
    End If
   
End Function

gdyaojie 发表于 2009-6-30 11:17:09

DoEvents要加在DO循环的循环体内, 不是放在外面.

另外, 如果定时器不是需要重复进入的话, 可以每次运算完毕后再触发下一次. 所以在定时器的代码第一行加:
Timer1.Enabled=false
最后一行加:
Timer1.Enabled=True

yuanshi3 发表于 2009-6-30 15:39:55

谢谢gdyaojie ,ConvertHexChr这个函数没有用到循环:

Function ConvertHexChr(str As String) As Integer
   
    Dim test As Integer
   
    test = Asc(str)
    If test >= Asc("0") And test <= Asc("9") Then
      test = test - Asc("0")
    ElseIf test >= Asc("a") And test <= Asc("f") Then
      test = test - Asc("a") + 10
    ElseIf test >= Asc("A") And test <= Asc("F") Then
      test = test - Asc("A") + 10
    Else
      test = -1                                    
    End If
    ConvertHexChr = test
   
End Function

zcllom 发表于 2009-6-30 15:44:12

楼主这么多上位机的问题怎么不去CSDN?
在这里问上位机就像在CSDN里问单片机。

yuanshi3 发表于 2009-6-30 16:06:33

去了的 这里的水平高
页: [1]
查看完整版本: 针对这个用doevents 在VB怎么解决啊