Making the SUB wait for something to happen

Inman

Well-Known Member
Licensed User
Longtime User
I have a For...Next loop and within the loop I need it to wait for the value of a variable to be under 10, before executing the next line. The value of this global variable is controlled by other functions. Here is how I do it currently.

B4X:
For i=0 to 10
.
.
.
.
Do While c>10
     DoEvents
Loop
.
.
.
Next

This code doesn't always work correctly. Also today I read in another thread that DoEvents can kill battery. It was mentioned that you could achieve a DoEvents effect with Timer. My question is how can I use Timer in the above routine, instead of DoEvents, to improve the code overall?
 

agraham

Expert
Licensed User
Longtime User
Android, like all modern GUI Operating Systems is event driven. You need to structure your programs accordingly. In an event-driven environment you "wait" for something to happen by returning from your Subs and waiting for an event to occur.

In your case whatever is changing the value of your variable c, presumably in response to an event of some sort, should also be checking for the required value and instigating whatever action is required. You shouldn't need a timer if it is your own code that is changing the variable value.
 
Upvote 0

Inman

Well-Known Member
Licensed User
Longtime User
It is for concurrent http requests. Just before an httpclient.execute, I increment a variable to count the request. I decrement this variable in the http responsesuccess as it means the http request has been completed. Now before the next httpclient.execute I need to make sure the concurrent request counter variable is less than 10 (as I dont want more than 10 concurrent requests). If it is >10, I wait till it is less than 10. The code is like:

B4X:
Sub somesub
.
.
.
.
request.InitializeGet(url)
request.Timeout = 10000
Do While connections>10
     DoEvents
Loop
connections=connections+1
If HttpClient1.Execute(request, i) = False Then Return
.
.
.
End Sub

Sub HttpClient1_ResponseSuccess (Response As HttpResponse, TaskId As Int)

connections=connections-1
.
.
.
.
End Sub

How can I get rid of DoEvents from this code?
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Exactly how depends upon the actual structure of your intended use. For example you could start your first ten in a loop and then set some global data as to how how many more and what requests are still needed then in the Response success and error events check if more requests are needed and if so execute them there. Managing some global flags and data and checking for outstanding requests in the Response events is the way I would go.

The fragment of code doesn't look like it handles TaskId properly but I guess you may have left that out.
 
Upvote 0

TomK

Member
Licensed User
Longtime User
Inman, are they concurrent AND persistent? In that there should always be 10 concurrent connections during the lifecycle of your app? Or are there a finite number of cycles?

ie., Do you need to establish 500 connections, then the cycle is complete?

If it's persistent, then I would imagine a background service is what you want, with a timer in it to check every X number of seconds (presumably the timeout value) for whether or not there are Y number of connections currently. Either way it sounds like a battery killer to me. (And have your app poll a global variable that you set with the current number of connections)


Just my $.02 for whatever it's worth

Tom
 
Last edited:
Upvote 0

Inman

Well-Known Member
Licensed User
Longtime User
Thanks for the tip, agraham. Sounds a bit complicated.

Tom, well these are image URLs. Within a loop there will be always about 10 to 40 images to download. Once the loop is completed, the user chooses another option and the loop will start again with some different parameters and image URLs but again there could be upto 40 images.

So every time the loop is executed there will be 40 images to download but I don't want to go beyond 10 downloads at a time due to fear of Rejection error.
 
Upvote 0

nfordbscndrd

Well-Known Member
Licensed User
Longtime User
I have a For...Next loop and within the loop I need it to wait for the value of a variable to be under 10, before executing the next line. The value of this global variable is controlled by other functions. Here is how I do it currently.

B4X:
For i=0 to 10
.
.
.
.
Do While c>10
     DoEvents
Loop
.
.
.
Next

This code doesn't always work correctly. Also today I read in another thread that DoEvents can kill battery. It was mentioned that you could achieve a DoEvents effect with Timer. My question is how can I use Timer in the above routine, instead of DoEvents, to improve the code overall?

I was the one having trouble with DoEvents in a loop. I was converting a program from VB6 that has DoEvents loops similar to what you described. I ended up changing the code to eliminate the loops.

Here is an example using your code:
B4X:
Sub Globals
     Dim i, c as Int
End Sub
 
Sub StartLoop
     i = 0
     DoFirstPartOfLoop
End Sub
 
Sub DoFirstPartOfLoop
    ' Execute code up to the point of the DoEvents loop, 
    ' then End Sub. The sub that changes "c" will eventually
    ' call DoSecondPartOfLoop which will then continue the
    ' loop by calling this sub (until i > 10).
     ...
End Sub     
 
Sub DoSecondPartOfLoop
    ' Execute code that comes after the DoEvents loop,
    ' then loop back to the first part of the loop:
    ... 
    i = i + 1
    If i <= 10 Then
        DoFirstPartOfLoop
    End If
End Sub
 
Sub CodeThatChangesC
    ' Execute code that changes "c" in your program:
    ...
    If c <= 10 Then DoSecondPartOfLoop
    ...
End Sub
 
Upvote 0
Top