Newbie needs help temporarily pausing loop

E

eejit

My code reads a text file and stores each line of text in an array.

I then loop through the array showing each line as a label.

At a certain point in the loop, I'd like to call a sub that pauses the
loop until the user clicks a button, at which point the loop
continues.

eg

for x = 1 to 20

label1.text = array(x)

if x = 10 then call pausesub()

next x


thanks for any help

eejit
 
R

R. MacDonald

Hello, eejit,

Look at the Thread.Sleep method (System.Threading namespace).

You will probably want to use "Thread.Sleep(Timeout.Infinite)" in this case.

Cheers,
Randy
 
E

eejit

Thanks Randy,


The thread.sleep(timeout.infinite) works great at pausing the program,
but do I have to create a seperate thread to handle a click event to
restart it?

I'm a complete hack at this, just trying to throw together a small
program,, and after reading about this threading stuff, I think my
head is going to explode.
 
J

Josef Brunner

Hi Randy,

eejit said:
Thanks Randy,


The thread.sleep(timeout.infinite) works great at pausing the program,
but do I have to create a seperate thread to handle a click event to
restart it?

one solution is to have a (member) variable and a loop where you always
sleep some time ... see this simple example:


Dim Counter As Integer = 0

Do While ConfigLoaded = False

Counter += 1

' Maximum time we wait is: 40 x 1000 Milliseconds = 40 seconds!

If Counter >= 40 Then

Exit Do

End If

If MyStopVariableIsTrue Then

MsgBox("Stopping the wait loop")



Exit Sub

End If

My.Application.DoEvents()

Threading.Thread.Sleep(1000)

Loop



Greets,

Josef
 
S

Stephany Young

Using Thread.Sleep with an infinite timeout is not a good idea is this case.

Not only does it put your loop to sleep forever, it also puts the entire
thread to sleep forever.

In the abscence of any evidence to the contrary, I am assuming that your
loop is somewhere in your UI thread and therefore your entire UI will be
suspended forever. This means that you will not be able to click your
button.

I would be inclined to use event driven nature of your application to your
advantage in conjunction with a simple re-entrant code technique.

If you have a class-level variable that contains the start value for your
loop then the whole thing becomes:

Private m_start As Integer = 1

Private Sub XXXX()

For x As Integer = m_start To 20
Label1.Text = array(x)
If x = 10 Then
m_start=11
Exit For
End If
Next

If x > 20 Then m_start = 1

End Sub

In the handler for the click event of your button, simply call XXXX.

The first time you call XXXX then is business as usual until it has
displayed the 10th array element. When this point is achieved the code exits
the loop (after setting the loop start variable) and the procedure, thus
freeing up the UI thread.

When your button is clicked, the call to XXXX means that the loop starts
from 11 and displays the remaing 10 array elements before exiting the loop
by dropping through the logic. This time the loop start variable is reset to
1 because the loop controller has passed it's limit of 20.

Another call to XXXX will start the whole thing over again.

Another point: The display of the array elements in the label will happen so
fast that the user will not be able to see them. You may need another delay
to slow the loop down.
 
R

R. MacDonald

Hello, eejit,

Re:
but do I have to create a seperate thread to handle a click event to
restart it?

Yes. And that will be too much trouble for what you are trying to do.
An approach similar to what Josef is suggesting is probably best for
your case.

But If you just want to wait for the user to push a button before
continuing, you really don't need a fixed time-out period (or even to
use the Sleep method). Here is another example, from a form with a
label and two buttons labeled "Run" and "Resume".

' This is a "member" variable (like Josef suggests).
Private mbooResumed As Boolean = False

Private Sub cmdRun_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles cmdRun.Click
' This button click starts a long "process".
mbooResumed = False
cmdRun.Enabled = False

' This is a "long" process that gets paused.
For intCount As Integer = 1 To 2000
Label1.Text = intCount
Application.DoEvents()
If (intCount = 1000) Then
WaitForResume()
End If
Next intCount

cmdRun.Enabled = True
End Sub

Private Sub cmdResume_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles cmdResume.Click
' This button click resumes the paused "process".
mbooResumed = True
End Sub

Sub WaitForResume()
' This routine pauses the "process".
While (Not mbooResumed)
Application.DoEvents()
' Using Sleep here is possible, but not required.
'Thread.Sleep(100)
End While
End Sub

I guess that using Sleep will reduce the load that your application
places on the system while it waits, but I would use a short sleep
interval (<=200 msec) to reduce latency after the user pushes the button.

Cheers,
Randy
 
M

mr_doles

I think the missing question here is what are you trying to do. The
easiest solution is to pop up a message box with an OK button at the
desired time. The problem is they can not do anything else while this
is up (is that the desired result?) Also Stephany is correct about not
being able to see the label change it will happen way to fast for the
user. Maybe you should fill a list box or text box line by line.
 
E

eejit

Thanks to everyone for their help on this.
I ended up using Stephanys method. I'm not sure why I didn't think of
something like this in the frist place.

thanks again
 
H

hayworth

I agree with Mr. Doles. A message box is by far the simplest way to do
it. I would do it that way unless you don't like the aesthetics of
that way for some reason (like wanting users to click a certain
particular button already existing on your GUI).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top