How to gracefully exit the middle of a nested routine when a user cancels?

(I use VB6, but I think it appears in most other languages.)

I have a GUI button that calls a procedure that takes a minute or two. I want impatient users to double-click on a button so that it gracefully exits the subprogram at any time.

I used a static variable to do this job very well (see code below), but I am cleaning up the project and I want to put the For / Next loop in my own function, since it is required in several different places in the project.

But this will break my static flag built into for / next, so I need to make some changes. Before I do anything related to public (global) variables, I thought that I would ask what other (smart, maybe actually educated CS) people did when faced with this problem.

So basically, my question is how do I replicate this:

Private Sub DoSomething_Click()

  Static ExitThisSub As Boolean ' Needed for graceful exit

  If DoSomething.Caption = "Click To Stop Doing Something" Then
    ExitThisSub = False ' this is the first time we've entered this sub
  Else ' We've re-entered this routine (user clicked on button to stop it)
    ExitThisSub = True ' Set this so we'll see it when we exit this re-entry
    Exit Sub '
  End If


  DoSomething.Caption = "Click To Stop Doing Something"

  For i = 0 To ReallyBigNumber
    Call DoingSomethingSomewhatTimeConsuming
    If ExitThisSub = True Then GoTo ExitThisSubNow
    DoEvents
  Next

  ' The next line was missing from my original example,
  ' prompting appropriate comments
  DoSomething.Caption = "Click To Do Something"

  Exit Sub

ExitThisSubNow:

  ExitThisSub = False ' clear this so we can reenter later
  DoSomething.Caption = "Click To Do Something"

End Sub

When do I move the for / next loop into my own function?

I think I changed ExitThisSub to the public variable QuitDoingSoManyLongCalculations, which will exit the new one for / next sub, and then DoSomething_Click in the same way.

But I always feel like a lover (what I am) when I use global variables - is there a more elegant solution?

0
source share
6

, . , . , , .

DoEvents. , Windows . , , . , , , QueryUnload .

Tag . .

. . , .

, , . , x, . , .

Option Explicit

Private Enum StopFlag
   NotSet = 0
   StopNow = 1
   StopExit = 2
End Enum

Private m_lngStopFlag As StopFlag
Private m_blnProcessing As Boolean

Private Sub cmdGo_Click()

   Dim lngIndex As Long
   Dim strTemp As String

   m_lngStopFlag = StopFlag.NotSet
   m_blnProcessing = True

   cmdStop.Visible = True
   cmdGo.Visible = False

   For lngIndex = 1 To 99999999

      ' check stop flag
      Select Case m_lngStopFlag

         Case StopFlag.StopNow

            MsgBox "Stopping - Last Number Was " & strTemp
            Exit For

         Case StopFlag.StopExit

            m_blnProcessing = False
            End

      End Select

      ' do your processing
      strTemp = CStr(lngIndex)

      ' let message loop process messages
      DoEvents

   Next lngIndex

   m_lngStopFlag = StopFlag.NotSet
   m_blnProcessing = False
   cmdGo.Visible = True
   cmdStop.Visible = False

End Sub

Private Sub cmdStop_Click()

   m_lngStopFlag = StopFlag.StopNow

End Sub

Private Sub Form_Load()

   m_blnProcessing = False

End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)

   Select Case UnloadMode

      Case vbFormControlMenu, vbFormCode

         If m_blnProcessing Then

            Cancel = True

            If MsgBox("Unload Attempted - Cancel Running Process?", vbOKCancel + vbDefaultButton1 + vbQuestion, "Test") = vbOK Then

               m_lngStopFlag = StopFlag.StopExit

            End If

         End If

      Case Else

         m_lngStopFlag = StopFlag.StopExit
         Cancel = True

   End Select

End Sub
+3

- , for . for ( ) . VB , , "" . , .

, , , : , , , ( - , ); GOTO for ( VB ?), , , , .

+2

- . , , .

, , , , .

+2

, ​​ bUserPressedCancel, DoEvents . , smelegant, .

- , - . , . , .

+2

, , . Tag . .

0

, 2 - GO STOP. STOP , GO. Click STOP - .

, STOP. , , , .

- ...

0

All Articles