针对这个用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文件,再次打开,就回出现串口占用,唯一的办法就是重启电脑。 这个里面没有要用到doevents的地方 在任务管理器中,关闭占用串口的程序试试。
再不然就用回调函数,不要让程序总在那儿等待。 用到循环的地方,建议都加上doevents 使CPU不至于死等 回2楼 在任务管理器中中根本就删除不了 唯一的办法就是重启电脑 否则就提示串口占用 你说回调函数怎么个回调法 谢谢!
回【3楼】 general_dwf,但是我VB里面发送命令的地方都没有用到循环啊。就如上面的命令。感谢! taskkill /f /t /pid xxx
xxx就是你进程的pid
必然能关上...
除非有双进程互锁... 不懂ls的“taskkill /f /t /pid xxx ”什么意思,能否具体说下 LZ发了这么多贴, 我的理解从你这块代码似乎看不到死机的原因, 你整个VB工程代码仔细检查过没有?
例如有没有用到定时器之类的?不定时假死有可能是别的地方引起的.
如果愿意, 可以把整个代码给我, 我帮你看看. 我也仔细检查过 单纯的往助手上发协议是很顺畅的 就是和下位机连接上后就有时候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 你的定时器多长时间触发一次?
这段代码本身没看到循环, 用到一个自己写的函数:strHexToByteArray, 该函数代码没看到. 按理应该不会引起界面假死.除非你的定时器的时间定得太短, 在上一次的事件处理没结束的情况下再次触发,如果是这种情况, 你可以尝试在定时器代码的前面加上: Timer1.Enabled=False, 进入代码就关闭定时器, 在代码最后加上Timer1.Enabled=true,看看情况有没有改善. 我看了下 就是下面用了循环:
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 问题应该出在这个strHexToByteArray函数, 在
For n = 1 To StringLen
后面加上DoEvents
还有后面的DO循环的第一行都加上DoEvents, 应该可以解除界面死锁的问题.
如果想替换掉字符串中的空格,可以使用replace函数.
另外, 你这个循环需要优化, 外层的FOR循环, 里面的两个DO循环, 都是字符串的长度, 循环的总次数是长度的几次方.如果定时器间隔很短, 会重复进入, 会导致意料不到的事情发生.
还有, 看到ConvertHexChr这个函数, 根据LZ的代码风格, 估计这个函数的代码也会用到循环, 建议LZ对 strHexToByteArray 所涉及到的代码进行优化, 因为strHexToByteArray是定时器要用到的, 本身定时器就是一个大循环, 这种密集运算的循环会占用CPU资源不放, 建议LZ在必要的地方放置DOEvents语句. 恩 好的 你说的除了这样修改还怎么修改(就加了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 DoEvents要加在DO循环的循环体内, 不是放在外面.
另外, 如果定时器不是需要重复进入的话, 可以每次运算完毕后再触发下一次. 所以在定时器的代码第一行加:
Timer1.Enabled=false
最后一行加:
Timer1.Enabled=True 谢谢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 楼主这么多上位机的问题怎么不去CSDN?
在这里问上位机就像在CSDN里问单片机。 去了的 这里的水平高
页:
[1]