本帖最后由 Eneboy 于 2012-05-07 00:41:19 编辑

解决方案 »

  1.   

    没细看你的代码,好像不全猜测是这样的:可能在你关闭的时候有 TIMER 还在执行;像你这样的情况( TIMER中有 DOEVENTS ),最好是等这类 TIMER 结束任务后,禁用掉(TIMER1.Enabled = False),然后再关闭进程;
      

  2.   

    如果咋调用TimeDelay延时5秒的过程中按了command2,就产生什么情况?窗体卸载,但是窗体过程还在运行,矛盾了:
    在ide里面,运行程序,command1后有输出,点了command2之后,程序没有终止,但是这个时候在ide里面暂停程序,会发现程序中止在TimeDelay过程里面.至少在TimeDelay里面循环的过程里面加上对退出状态的检查,以便能及时退出.
    Public Sub TimeDelay(delayMilliseconds As Long)没有写2个Timer的时间设置,如果两个Timer处理过程用了1秒,而timer是0.5秒触发一次,也会有问题.timer对象似乎不可重入,而已两个timer会互相影响.
    Option Explicit
    Dim bexit As Boolean
    Private Sub Form_Load()
    Debug.Print NUm & "  Load me ..."
    NUm = NUm + 1
    Open "c:\yw.txt" For Output As #1
    '没有文件关闭的语句,程序结束后系统会自动写入文件,并且关闭文件
    End SubPrivate Sub Timer1_Timer()
    'Timer1.Interval=20'变态设置,在20ms循环根本不结束的.
    Dim i, j, a, b
    a = Timer
    For i = 1 To 1200
            For j = 1 To 1200
                    b = j
                    DoEvents
                    'If bexit = True Then Exit Sub
            Next
    Next
    Print #1, "Timer1 " & Timer, Timer - a
    End SubPrivate Sub Timer2_Timer()
    'Timer1.Interval=30'变态设置,在30ms循环根本不结束的.
    Dim i, j, a, b
    b = Timer
    For i = 1 To 1200
            For j = 1 To 1200
                    a = j
                    DoEvents
                    'If bexit = True Then Exit Sub
            Next
    Next
    Print #1, "Timer2 " & Timer, Timer - b
    End Sub
    输出文件Timer2 36721.02              1.609375 
    Timer2 36722.63              1.578125 
    Timer2 36724.23              1.578125 
    Timer2 36725.89              1.625 
    Timer2 36727.5               1.578125 
    Timer2 36729.22              1.6875 
    Timer1 36730.63              11.21875 timer1的运行受到了影响,编译和不编译都是受影响的
      

  3.   

    还是在循环,长时间的操作里面判断退出标志,有退出标志了就不循环了.退出前关闭所有timer.
      

  4.   

    这个显然和DoEvents没有关系,是你没有用好的原因。建议你仔细检查,在退出陷入死循环时,点击:Ctrl+Break,终止运行,看看程序步停在什么地方,再单步执行,一般都能发现问题所在。
      

  5.   

    各位老师,我重新发我写的程序,完整的,请大家调试'此语句放在一个独立的 module 中
    Public Declare Function GetTickCount Lib "kernel32" () As Long'以下都在窗体中,窗体包含 2个定时器,2个按钮,1个标签,1个文本矿
    Private bIsExit As Boolean
    Private bIsWaiting As Boolean, bIsProcess As Boolean
    Private TimeLen As Integer
    '=======================================================
    '程序功能:点击开始 Command2 时,程序每隔5秒输出当前时间
    '该程序问题:单击结束按钮 Command2  时无法结束
    '=======================================================Public Sub TimeDelay(delayMilliseconds As Long)
    '-----------------------
    '为程序进行延时的子过程
    'Do Until 条件.........loop '这个条件是为假才会执行 直到为真停止
    '-----------------------
      On Error Resume Next
      
        '此处加上程序退出判断
        If bIsExit Then
            Exit Sub
        End If
        
      Dim sngStartTime As Single                        '该变量用来记录开始时间
      sngStartTime = GetTickCount                       '开始时间为计算机的开机时间
      Do Until (GetTickCount - sngStartTime) > delayMilliseconds
          DoEvents                                      '转让控制权
      Loop
    End SubPrivate Sub Command1_Click()
        '开始按钮
        Timer1.Enabled = True
        Text1.Text = "开始时间:" & Now
    End Sub
    Private Sub Start()    If bIsExit Then
            Exit Sub
        End If
        
        TimeDelay (TimeLen)     '延时
        
        Text1.Text = Text1.Text & vbNewLine & "输出时间:" & Now
        Text1.SelStart = Len(Text1.Text)
    End SubPrivate Sub Command2_Click()
        '结束按钮
        Timer2.Enabled = False
        bIsExit = True
        Unload Me
    End SubPrivate Sub Form_Load()
        bIsExit = False
        TimeLen = 5000  '设置输出时间间隔
    End SubPrivate Sub Timer1_Timer()
        '定时器参数设置为 1秒
        Call Start
    End SubPrivate Sub ShowTime()
        lblTime.Caption = Now
    End SubPrivate Sub Timer2_Timer()
        '定时器参数设置为1秒,显示当前时间
        Call ShowTime
    End Sub
      

  6.   


    已经关闭 timer ,但是还是无法关闭程序。
      

  7.   

    问题出在 TimeDelay 过程中;Do Until (GetTickCount - sngStartTime) > delayMilliseconds把上面的《大于号》改成《小于等于》就行了;Do Until (GetTickCount - sngStartTime) <= delayMilliseconds
      

  8.   

    拜托 内部死循环了吧  不用 doevents 延时 用个timmer控件不行吗 
      

  9.   

    不对吧,8楼兄弟,是你搞反了,untill 条件后就跳出循环了。
      

  10.   

    do while doevents 
      ...
    loopdo 。。doevents ,。。loop 本身就是毫无意义的延时只有多线程的计时器事件那个api能保证稍微精准些,其他的延时一概没有意义
    为了保持控制权,timer 事件足够了,timer不准确还存在系统级问题,这是不可避免的,也并非全是时间不准确的问题;每个线程只运行20ms;怎么可能让一个timer持续占用时间片考虑新的思路吧
      

  11.   

    靠!!! csdn也跟百度是的,吞楼了是吗、?
      

  12.   

    本帖最后由 bcrun 于 2012-05-27 16:52:44 编辑
      

  13.   

    本帖最后由 bcrun 于 2012-05-27 16:49:47 编辑
      

  14.   

    本帖最后由 bcrun 于 2012-05-27 16:52:12 编辑
      

  15.   

    本帖最后由 bcrun 于 2012-06-21 09:59:25 编辑
      

  16.   

    在你的代码中,禁用 Timer 仅仅是使它下一次不触发 OnTimer 事件,并不能停止当前的循环操作。如下:Dim blnStop As BooleanPublic Sub TimeDelay(delayMilliseconds As Long)
    '-----------------------
    '为程序进行延时的子过程
    'Do Until 条件.........loop '这个条件是为假才会执行 直到为真停止
    '-----------------------
      On Error Resume Next
      
        '此处加上程序退出判断
        If bIsExit Then
            Exit Sub
        End If
        
      Dim sngStartTime As Single                        '该变量用来记录开始时间
      sngStartTime = GetTickCount                       '开始时间为计算机的开机时间
      Do Until (GetTickCount - sngStartTime) > delayMilliseconds
          DoEvents                                      '转让控制权
           If blnStop Then Exit Do                       '检查停止标志
      Loop
    End SubPrivate Sub Command2_Click()
        '结束按钮
        blnStop = True
        Timer2.Enabled = False
        bIsExit = True
        Unload Me
    End Sub
      

  17.   

    当然,也可以这样,省掉 blnStop 变量:Public Sub TimeDelay(delayMilliseconds As Long)
    '-----------------------
    '为程序进行延时的子过程
    'Do Until 条件.........loop '这个条件是为假才会执行 直到为真停止
    '-----------------------
      On Error Resume Next
       
      '此处加上程序退出判断
      If bIsExit Then
      Exit Sub
      End If
        
      Dim sngStartTime As Single '该变量用来记录开始时间
      sngStartTime = GetTickCount '开始时间为计算机的开机时间
      Do Until (GetTickCount - sngStartTime) > delayMilliseconds
      DoEvents '转让控制权
      If Not Timer1.Enabled Then Exit Do '***************** 检查停止标志
      Loop
    End SubPrivate Sub Command2_Click()
      '结束按钮
      Timer1.Enabled = False  '不明白你原来禁止 Timer2 的用意
      bIsExit = True
      Unload Me
    End Sub
      

  18.   

    本帖最后由 bcrun 于 2012-06-27 14:48:50 编辑