Listening for an event in the middle of a function/sub

Posted on 2003-02-26
Medium Priority
Last Modified: 2013-11-13
Is there a way to listen for an event in the middle of a function or subroutine? Or better yet to wait for an event to occur before continuing on?

I have a fairly complex program but in the heart of it I am making a connection to a server (using winsock) and running some commands to get some information about accounts on the server.

The only problem I am running into is that there is no way to pause the program long enough for the remote server to send a response.  I know I can use the event functions (winsock_DataArrival) to determine what I want to do when an event occurs, but using those entirely means I end up with some really bad spagetti code.  I would like to to something like this:

LogonToServer      'Handles all of the sign on procedures

For ifor = 0 To 30
  winsock.SendData "/accountdata " & aAccount(ifor)
  'wait for a response from server.. this is what I can't do
  winsock.GetData aAccountInfo(ifor)
Next ifor


That was just a rough idea of what I am trying to do, anyone have any ideas? Or is this not possible at all?


Question by:JWood
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Accepted Solution

rinkujain earned 150 total points
ID: 8031391

For listening/Switching in between a process you shd use
DoEvents Fuction .
Some related help from msdn :

Although Timer events are the best tool for background processing, particularly for very long tasks, the DoEvents function provides a convenient way to allow a task to be canceled. For example, the following code shows a "Process" button that changes to a "Cancel" button when it is clicked. Clicking it again interrupts the task it is performing.

' The original caption for this button is "Process".
Private Sub Command1_Click()
   ' Static variables are shared by all instances
   ' of a procedure.
   Static blnProcessing As Boolean
   Dim lngCt As Long
   Dim intYieldCt As Integer
   Dim dblDummy As Double
   ' When the button is clicked, test whether it's
    'already processing.
   If blnProcessing Then
      ' If processing is in progress, cancel it.
      blnProcessing = False
      Command1.Caption = "Cancel"
      blnProcessing = True
      lngCt = 0
      ' Perform a million floating-point
      ' multiplications. After every
      ' thousand, check for cancellation.
      Do While blnProcessing And (lngCt < 1000000)
         For intYieldCt = 1 To 1000
            lngCt = lngCt + 1
            dblDummy = lngCt * 3.14159
         Next intYieldCt
         ' The DoEvents statement allows other
         ' events to occur, including pressing this
         ' button a second time.
      blnProcessing = False
      Command1.Caption = "Process"
      MsgBox lngCt & " multiplications were performed"
   End If
End Sub

DoEvents switches control to the operating-environment kernel. Control returns to your application as soon as all other applications in the environment have had a chance to respond to pending events. This doesn't cause the current application to give up the focus, but it does enable background events to be processed.

The results of this yielding may not always be what you expect. For example, the following Click-event code waits until ten seconds after the button was clicked and then displays a message. If the button is clicked while it is already waiting, the clicks will be finished in reverse order.

Private Sub Command2_Click()
   Static intClick As Integer
   Dim intClickNumber As Integer
   Dim dblEndTime As Double
      ' Each time the button is clicked,
      ' give it a unique number.
   intClick = intClick + 1
   intClickNumber = intClick
      ' Wait for ten seconds.
   dblEndTime = Timer + 10#
   Do While dblEndTime > Timer
      ' Do nothing but allow other
      ' applications to process
      ' their events.
   MsgBox "Click " & intClickNumber & " is finished"
End Sub

You may want to prevent an event procedure that gives up control with DoEvents from being called again before DoEvents returns. Otherwise, the procedure might end up being called endlessly, until system resources are exhausted. You can prevent this from happening either by temporarily disabling the control or by setting a static "flag" variable, as in the earlier example.

Avoiding DoEvents When Using Global Data
It may be perfectly safe for a function to be called again while it has yielded control with DoEvents. For example, this procedure tests for prime numbers and uses DoEvents to periodically enable other applications to process events:

Function PrimeStatus (TestVal As Long) As Integer
   Dim Lim As Integer
   PrimeStatus = True
   Lim = Sqr(TestVal)
   For I = 2 To Lim
      If TestVal Mod I = 0 Then
         PrimeStatus = False
         Exit For
      End If
      If I Mod 200 = 0 Then DoEvents
   Next I
End Function

This code calls the DoEvents statement once every 200 iterations. This allows the PrimeStatus procedure to continue calculations as long as needed while the rest of the environment responds to events.

Consider what happens during a DoEvents call. Execution of application code is suspended while other forms and applications process events. One of these events might be a button click that launches the PrimeStatus procedure again.

This causes PrimeStatus to be re-entered, but since each occurrence of the function has space on the stack for its parameters and local variables, there is no conflict. Of course, if PrimeStatus gets called too many times, an Out of Stack Space error could occur.

The situation would be very different if PrimeStatus used or changed module-level variables or global data. In that case, executing another instance of PrimeStatus before DoEvents could return might result in the values of the module data or global data being different than they were before DoEvents was called. The results of PrimeStatus would then be unpredictable.

For More Information   See "DoEvents Function" and "Refresh Method" in the Language Reference.

Author Comment

ID: 8035231
Not exactly the purpose I would have assumed for that function, but it solves my problem perfectly.  Thanks for the help.

Featured Post

Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There is an easy way, in .NET, to centralize the treatment of all unexpected errors. First of all, instead of launching the application directly in a Form, you need first to write a Sub called Main, in a module. Then, set the Startup Object to th…
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
This video teaches viewers about errors in exception handling.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question