Avatar of MiSheps
MiSheps
Flag for United States of America asked on

How to best use MultiThreading?

Greetings Experts,

Ok...  here is the problem that I'm having:

I have an application that runs in a continuous loop in conjunction with a second application. The two sister apps run side by side all day long, feeding information back and forth to eachother through DDE. The way that the loop is currently set up is a simple, send information, wait for a response, and for new information to continue, as such...

1) App A, sends a "green light" to App B using DDE communication
2) App B, then receives the "Green Light" message, and processes part a loop 1 time.
3) App B, sets itself to a "red light" (stop) and prepares a message for App A to grab indicating that it has stopped.
4) App A, then processes through a loop of proceedures 1 time, and then
5) App A, stops, and sends a message (Green light) back to App B so that App B can loop again while App A waits again.

Etc, etc, etc.

That part seems to work well... but here is the problem:

While App A is waiting for App B to finish, you can't do anything in App A..... But... I need to be able to. Specifically in App A, I need to be able to click on a hot spot, which then activates and unhides (shows) a sub form of App A, which I need to be able to navigate withouth delay.

So, what I want, is while App A is waiting for App B to send back a message that it is done with its loop, that App A is still able to function,... OR, at least that the sub form of App A is able to function, even though the main part of App A is still waiting for the message back from App B before it continues with its code.

Currently, when you click on the hotspot, it does nothing until App A is in its loop process. And then as soon as App A stops its loop, and App B starts its loop, the sub form of app A is dead in the water as well, until app B is done processing its loop and given control back to App A.

One thing to keep in mind, the time it takes for App A to loop through its processes is only about 2 seconds, as well as App B... (which is what makes it so annoying to keep having to wait for it to get focus back....

Any ideas, or suggestions would be very appreciated!

Thanks!
Visual Basic Classic

Avatar of undefined
Last Comment
nffvrxqgrcfqvvc

8/22/2022 - Mon
Mike Tomlinson

"So, what I want, is while App A is waiting for App B to send back a message that it is done with its loop, that App A is still able to function"

How are you currently making AppA wait for AppB to finish?
MiSheps

ASKER

Basically what I'm doing is using DDE to pull a message from a text box in App-B which indicates that it is ready to switch to App-A.

So,... in App-B, when it has run through its loop, it populates a text box (CrossAppText) with a message that says "ACM Admin is Running".

While App-A is waiting for App-B to finish, it loops every 2 seconds, and pulls the CrossAppText.Text from App-B via DDE. When it detects that the Text Box says "ACM Admin is Running" it then knows that it can continue, breaks out of its loop and proceeds to process the rest of the loop for App-A. When it is ready for App-B to start it's loop again, it changes the CrossAppText.text box in App-A to "ACM User is Running" and then does a LinkPoke to pupulate the text box in App-B to read as "ACM User is Running" which App-B is listening for to process its loop, etc, etc etc, over and over all day.

Here is the code that you requested of how I am waiting in App-A for App-B to finish:

'##################################################################
'##################################################################
RestartACMAdminProcs:
    DoEvents
   
    ApplicationControlManagerMain.CrossAppText.LinkRequest
    ApplicationControlManagerMain.CrossAppText.Refresh
   
    If ApplicationControlManagerMain.CrossAppText.Text = "ACM Admin is Running" Then
        StatusSplash.ActiveAppShape1.FillColor = vbGreen
        StatusSplash.ActiveAppShape1LBL.Caption = "Processing ACM Admin"
        StatusSplash.ActiveAppShape1LBL.Refresh
        StatusSplash.ActiveAppShape1.Refresh
        GoTo JumpACMRunCheck
    End If
    DoEvents
    Sleep 2000
    GoTo RestartACMAdminProcs

JumpACMRunCheck:

'Processes the rest of the loop at this point

'##################################################################
'##################################################################

And to set App-B into it's loop processing I use the following code:

'##################################################################
'##################################################################
    StatusSplash.ActiveAppShape1.FillColor = vbRed
    StatusSplash.ActiveAppShape1LBL.Caption = "Processing ACM User"
    ApplicationControlManagerMain.CrossAppText.Text = "ACM User is Running"
    ApplicationControlManagerMain.CrossAppText.Refresh
    StatusSplash.ActiveAppShape1LBL.Refresh
    StatusSplash.ActiveAppShape1.Refresh
    ApplicationControlManagerMain.CrossAppText.LinkPoke
'##################################################################
'##################################################################

I appreciate your taking the time to help!
Mike Tomlinson

I believe all you need to do is REDUCE the amount of time that AppA is sleeping:

    Sleep 2000

During a Sleep Interval the app cannot respond to user interaction or repaint itself.  A long interval will result in a "sluggish" application.  You already have DoEvents in place which allow it to process its queued messages...so try a smaller interval, such as closer to only 100 milliseconds:

    Sleep 100

All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
MiSheps

ASKER

Yes, that does improve the response time a bit, but unfortunately it trashes the processor (100% spikes). The response back from App-B, so that App-A can restart its loop, could take anywhere from 2 seconds to 10 minutes. Spiking the proc once every 2 seconds (2000 miliseconds) keeps the processor utilization down and managable. When I set it to 100 the Proc CPU usage history looks like the Swiss Alps! lol

What I need, is the ability to pause the App-A until it gets the response back from App-B, BUT... still be able to access other functions off of a sub form on App-A without delay.

Basically, they way that App-A is laid out is like this:
App-A starts with the following layout:

1) The main form doing all of the processing Starts
2) A sub form (which is just two status dots) starts and sits "On top of all windows"

Part (1) (which does all the processing) is what loops constantly.

Part (2) is what I want to be able to run without delay. Or, more specifically what happens when part (2) is clicked.

When you click part (2) (which is a sub form of the main project) it activates and shows a Third sub form (A Status Splash screen). This screen is a Dashboard sort of setup. This in particular is what I want to be able to function without delay.

The dashboard (Sub Form 3) has several tabs, most of wich are visual status updates, but some of which are functions.

What I need to be able to do is:

While the Main form (1) is processing its loop, and waiting for "App-B" to give the restart indicators, I still need the ability to click on Sub Form (2) to be able to access without delays sub form (3).

When I reduce teh sleep time in the loop from 2000 to 100, it does improve the response time, but it still does function the way that I want. Reducing it to 100 has two adverse affects:
1) It spikes the processor utilization
2) it still acts sluggish. Because while it is interlooping (back to RestartACMAdminProcs:) even with the "doevents" it still doesn't seem to be responsive while in "ACM User is running" mode. My guess is maybe because the processor is spiked?

Thats kinda why I thought using a multi-threaded environment would work well, (though I don't know much about multithreading). But in my mind... my app should actually run in two threads:

1) The first thread would run the main form (which does all the looping, etc)
2) The second thread would handle the sub form functions when Sub form 2 is clicked to activate sub form 3, and then all action items in sub form 3.

I appreciate your help and ideas very much idol mind.... Any other thoughts/ideas?



Mike Tomlinson

Well...VB6 has no intrinsic support for true multithreading...so if you want the correct approach you're going to have to dive into low level API usage.  Instead of DDE you could create a mutex and check for it in your own message pump.  The apps take turns signaling the mutex and waiting for each other.  It's messy and a pain in the butt...

Mutex: http://msdn.microsoft.com/en-us/library/ms684266(VS.85).aspx
MsgWaitForMultipleObectsEx: http://msdn.microsoft.com/en-us/library/ms684245(VS.85).aspx

Here is a partial example of the kind of code you would need:
http://undim.blogspot.com/2006_08_13_archive.html

It's not really what you are looking for but it should give you an idea of the approach that's needed...this type of example (combining a Mutex with QS_ALLEVENTS) is pretty hard to find in VB6...   =\
MiSheps

ASKER

Yikes....

The bad news is that your suggestion is a little over my head....

But the good news is...

...I was riding home from work on the Harley, and thinking about this little problem during the 4 hour ride, and I think I may have the answer to my problem. My delay on my app seems to be caused specifically by the wait that the app experiences while waiting for the DDE response...

But... when I go into the status section of the sub form, I really don't need the app to loop through that particular section of code. And there in lies the answer... I think...

I'm thinking that I will just set up a boolean that triggers when I click on the sub app, and jumps that section of the loop all together, but allows the rest of the loop to cycle until the sub form is closed again. then it will trigger the boolean back and allow the dde message pull to work again.

Unfortunately I can't try this straight away, but I just wanted to post an update since you have been so helpful so far. I'll let you know the results, and if it doesn't work, I would love further help.

Also, if you have any other brainstorm ideas, that don't involve rocket science, let me know!

Thanks again for all your help!





⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
ASKER CERTIFIED SOLUTION
nffvrxqgrcfqvvc

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.