0

I'm new to programming in general, so please bear with me.

This VB6 program I'm using (I'm new at a job) uses an older, but updated Borland C++ DLL (which I'm also updating) to get a part list from.

Everything works fine in debug mode in the VB6 IDE, but when I create an actual executable file and try it, it crashes. The "fix" for this was already implemented years before I got here, they added a bunch of WaitFor function calls to "slow VB6 down so it can finish reading from the DLL before moving on."

The weird thing is, I'm updating the VB6 code by placing some of the hard-coded if-checks for specific parts and putting it into the DLL, because they couldn't get the Borland C++ DLL updated previously. The side-effect of course is that the VB6 code is running faster.

I've narrowed the problem down to simply timing. There is one section where if I just add a simple MsgBox, it won't crash, but WaitFor, even if set to 100000... won't work.

So my question is, can I prevent the VB6 code from moving on without finishing reading from the DLL without arbitrarily adding WaitFors, etc. This seems like a poor practice and I'm going to be at this company for awhile and don't want to continue this trend.

Thank you!


Update:

Doing this in place of the MsgBox seems to make it work as well:

Dim x as Long
Dim y as Long
For x= 1 to 500
    y = y + 1
Next

Simply adding that nonsense fixes the issue.


The WaitFor function:

On Error Resume Next
Static dLastDoevents  As Double
Dim SleepyTime        As Integer:   SleepyTime = 20     'set "Sleep peroid" in milliseconds (this is also the resolution of the doevents rate)
Dim DoEventsRate      As Integer:   DoEventsRate = 200     'set "DoEvents rate" in milliseconds
Dim iSleepTimes       As Integer:   iSleepTimes = Int(MilliSeconds / SleepyTime)
Dim msLeftOver        As Integer:   msLeftOver = (MilliSeconds - (iSleepTimes * SleepyTime))
Dim dNow              As Double
Dim i                 As Integer

If MilliSeconds < 0 Then MilliSeconds = 0

dNow = Timer
If dNow > (dLastDoevents + (DoEventsRate / 1000)) Or dLastDoevents = 0 Or dLastDoevents > dNow Then
  DoEvents                  'DoEvents if it's been long enough according to the DoeventsRate
  dLastDoevents = Timer
End If

If iSleepTimes > 0 Then
  For i = 1 To iSleepTimes
    Sleep (SleepyTime)      'Sleep at intervals of SleepyTime
    dNow = Timer
    If dNow > (dLastDoevents + (DoEventsRate / 1000)) Or dLastDoevents = 0 Or dLastDoevents > dNow Then
      DoEvents              'DoEvents if it's been long enough according to the DoeventsRate
      dLastDoevents = Timer
    End If
  Next i
End If

If msLeftOver > 0 Then
  Sleep (msLeftOver)        'Sleep for the remainder of milliseconds if needed (ie WaitFor 5)
  dNow = Timer
  If dNow > (dLastDoevents + (DoEventsRate / 1000)) Or dLastDoevents = 0 Or dLastDoevents > dNow Then
    DoEvents                'DoEvents if it's been long enough according to the DoeventsRate
    dLastDoevents = Timer
  End If
End If
Keith
  • 1,331
  • 2
  • 13
  • 18
  • Is the C++ DLL using background threads? (I can't think of any other situation where a calling routine would have to "wait for" another routine to finish.) – prprcupofcoffee Mar 20 '14 at 14:05
  • 1
    is this WaitFor a function they made themselves? If so, could you post it? The WaitFor() probably has some DoEVents which doesn't block execution like your fixed loop to 500 does. – Hrqls Mar 20 '14 at 14:26
  • Oh my goodness. I assumed that wasn't their function. I'm new to VB. Yes, they have a timer (for the passed milliseconds). It calls DoEvents until the timer is up. – Keith Mar 20 '14 at 14:41
  • 1
    what are they waiting for? it is bad practice to wait a specific time, or to loop to a specific number just for something to finish .. it would be better to set a flag or raise an event when the action is complete – Hrqls Mar 20 '14 at 15:32
  • They just add the wait in there so it doesn't crash "getting ahead of the DLL." The senior programmer who explained it to me said that it's a VB6 issue and that was the only way to fix it. I guess I'm just double-checking to see if anyone else has this sort of experience and possibly know a better way. I agree 'waits' are terrible. – Keith Mar 20 '14 at 17:19

1 Answers1

1

On debug mode, Visual Basic 6 IDE does not compile to native code (it interpretes P-Code) and because of that your code behaves differently to the point it crashes when run from exe. You can produce an .exe that uses P-Code but it is not recommended. (It somewhat slows down execution but seems like you want to slow things down).

As mentioned in the comment section, WaitFor is not a VB function and VB6 is not known for its easy multi-threading capabilities. It's hard to find out from here why it crashed but DoEvents is known to cause crashes due to stack overflows.

Since you have access to both codes, I'd suggest modifying both them to provide an event based mechanism. If you don't use COM or don't want to raise COM events, you can also use alternative communication channels like named pipes to tell VB6 that work is finished.

Community
  • 1
  • 1
Furkan Omay
  • 1,047
  • 1
  • 11
  • 22