Hi,
I'm trying to add pauses into one of my programs. If the pause is in a loop, the system hangs up on it. As a simple example, the following works fine - it waits 4 seconds then puts "5" in the label box:
Dim g As Integer = 5
System.Threading.Thread.Sleep(4000)
Label1.Text = g
The following code, however, doesn't work. It just hangs up and does nothing:
Dim
g As Integer For g = 1 To 10System.Threading.Thread.Sleep(4000)
Label1.Text = g
NextI'm just trying to throw in a pause during each iteration of the For loop.
I've tried the things mentioned in the threads "A Pause with a Loop" and "Simple delay needed", but nothing works. I'm using Visual Basic Express Edition 2005.
Any suggestions
Bob

Simple Pause
CSharpZealot
I had a Commodore 64 and later a Commodor 128-D. Those were great little machines. I never had an Atari computer. I had an Atari 2600 game console (can you call that a game console ).
PankajGautam
Bob,
By the sounds of it, your experience has been with that of a more sequential type of programming language. It was fairly difficult for me when I made the switch to event based programming as well. Later, you learn to design your entire programms differently and they usually come out more efficient. I think that you can do what you are asking though, try the following;
Public
Class Form1 Dim index As Integer = 0 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.LoadTimer1.Interval = 10
Timer1.Enabled =
True End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.TickTimer1.Interval = 1000
Select Case index Case 0 To 2Label1.Text =
"Im doing some code" Case 3 To 5Label1.Text =
"Im waiting around" Case ElseLabel1.Text =
"Im doing some more code" End Selectindex += 1
End SubEnd
Classgibic
If your prepared to accept a dead UI for 3 seconds then you can Use thread.sleep
If your not then you can code alternatives - heres another than will maintain UI responsiveness during the 6 seconds delay.
Public Class Form1
Dim b As Boolean = False
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Timer1.Interval = 6000
Proc1()
Proc2()
Timer1.Enabled = True
Do Until b = True
Application.DoEvents()
Loop
b = False
Proc3()
End Sub
Sub Proc1()
Label1.Text = "Proc1"
Application.DoEvents()
End Sub
Sub Proc2()
label1.text = "Proc2"
Application.DoEvents()
End Sub
Sub Proc3()
label1.text = "Proc3"
Application.DoEvents()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
b = True
Timer1.Enabled = False
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MsgBox("Foo")
End Sub
End Class
FahimAshfaq
Use flags. Allow the UI to do everything it needs, and set flags to indicate the 'status' of the application.
However, you have to understand that programming is waaaay different from the olden days. Windows is event based: nothing happens unless some kind of event occurs.
One other item is that you need to avoid locking up your user interface at all costs. If you have a long running task (for example, a task that needs to be activated when button B is pushed), you can fire off a thread to do so. However, it sounds like your tasks are very short and unobtrusive, so threading is probably not necessary.
Without fully knowing what you are trying to achieve, have each task set a 'state' variable. Each task will execute when the state variable is a certain value. It'll increment the state at the end. Use a timer with a big case statement (brute force, but may work for a small number of tasks). Something like this:
Sub Task1
Do Stuff
State += 1
End Sub
Sub Task2
DoStuff
State+=1
End Sub
Timer()
select Case State
Case 0
' Do Nothing: Wait for State to be set
Case 1
Call Task1
Case 2
Call Task2
case 3
State = 0
End Select
end sub
udiraz
So some examples of delaying and reasons why some approaches are bad , I would suggest you try them - the examples use a simple form with a couple of buttons on and the final one has a timer control on the form.
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim g As Integer
For g = 1 To 10
System.Threading.Thread.Sleep(1000)
Label1.Text = g
Next
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MsgBox("Hello")
End Sub
End Class
This is bad, a 1 second delay using thread sleep - try clicking the button to start the process and then clicking the second button after the process starts to display the msgbox. The label doesnt update until the end.
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim g As Integer
For g = 1 To 10
Application.DoEvents()
System.Threading.Thread.Sleep(1000)
Label1.Text = g
Next
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MsgBox("Hello")
End Sub
End Class
This is better as it updates the label and msgbox would respond but lets say I wanted a 10 second delay between loops
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim g As Integer
For g = 1 To 10
Application.DoEvents()
System.Threading.Thread.Sleep(10000)
Label1.Text = g
Next
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MsgBox("Hello")
End Sub
End Class
Sure the label updates but now you seeing that the UI is unresponsive while it is waiting. Its the self same code as above just with a longer delay.
If you want a delay but want to keep the UI responsive then one approach may be to use a timer control to achieve a preset delay for the loops whilst making the UI remain responsive.
Public Class Form1
Dim g As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'//Start Timer
g = 0
Timer1.Interval = 10000 'Duration of 10 seconds
Timer1.Enabled = True
If g >= 10 Then Timer1.Enabled = False '//Stop on 10th Iteration
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MsgBox("Hello")
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
g = g + 1
Label1.Text = g
End Sub
End Class
So the final solution would enable you to add a long delay but also allow the user interface to remain responsive during this delay. Whne you start it the time will update every 10 seconds but the second button will remain clickable and functional throughout.
So thread.sleep is not a particularly good solution for items where the program still has to do things during the delay or where the UI needs to remain responsive.
As for you code - putting it in the form load will never display the label changes as it is in the form load event - this event is run before the form is visible. Hence you would only see the last value present (10) when the form eventually is loaded and becomes visible.
And the second comment on the C64 code - was that this intentional looping to slow things down. Speed is a great difference you are looking a 1 MHz processor for a C64 as against a even modest spec PC being a 1.5 GHz machine and you are looking at interpreted code on a C64 as against and optimized compiled code in VB.NET
Things have changed a lot and putting a loop like that to delay yourself - wont work as the compiler will optimize this and modern machines process this extemely quickly, How quickly, put the following code in a button click event and you'll see how quickly it iterates around a loop 1000000 times.
Dim swatch As New Stopwatch()
swatch.Start()
For i = 1 To 1000000
Next
swatch.Stop()
MsgBox(swatch.Elapsed.TotalMilliseconds)
Hope that gives you a clear indication as to some methods for delaying and why old methods used 20 years ago not longer work today.
jlento
As we seem to have demonstrated numerous ways to implement a pause I think you need to determine which is most specific to you needs and plump for an approach.
If you can withstand the application being dead for the delay then thread.sleep will work - if not then a timer approach may work for you.
Either way I think you have enough choices on here that pitfalls of each have been demonstrated,
redundent
We're getting there, but it's still not doing what I want. So here's the code in my trial program:
Public
Class Form1 Dim g As Integer Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.LoadTimer1.Interval = 1000
Timer1.Enabled =
TrueLabel2.Text =
"count running" End Sub Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tickg = g + 1
Label1.Text = g
If g >= 10 ThenTimer1.Enabled =
FalseLabel2.Text =
"count done" End If End SubEnd
ClassWhat it does is put "count running" in label 2, it counts 10 seconds off in label 1, and then it prints "count done" in label 2 after the 10 seconds.
Here's the problem - I don't want to see "count running" until the counter is done. In fact, inject 200 lines of code after the --Label2.Text = "count running"-- line. I don't want any of them to execute until the timer is done. I want everything to stop.
That's what I'm trying to do - I want a line of code in various places in my bigger program that says "OK - EVERYTHING stop where you are for a couple of seconds".
I guess my confusion lies in the fact that there doesn't seem to be order in the execution of the code. It runs everything simultaneously instead of going:
Step 1: do this
Step 2: do this
Step 3: wait three seconds
Step 4: do this
Step...
Bob
michael_miguel
Here's my entire program, with Brendan's suggestion:
Public
Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim g As Integer For g = 1 To 10Application.DoEvents()
System.Threading.Thread.Sleep(500)
Label1.Text = g
Next End SubEnd
ClassWhen I lowered the sleep time, I realized what the code is doing: It's running the Sleep line all ten times before it gets to the "Label1.Text = g" line. Either that, or it's just not opening the form until all ten pauses are done.
So this is what I see: after I start, it counts to 5s (500ms * 10) and then opens up the form and puts a "10" in Label1. I assume that it's printing 1 through 10 but it's too fast for me to see, but this may not be the case.
This is just a trial program I'm writing to understand how to make a pause work. My actual program is a card game where you play against multiple computer opponents. I just want pauses thrown into various places so that I can see the computer's play unfold at a reasonable pace, instead of having five players act instantly.
How do I make the program stop what it's doing for a second or two, and then continue on where it left off
It was a piece of cake on my Commodore 64, 20 years ago, for God's sake:
10 for t = 1 to 600
20 next t
Couldn't be any simpler.
Bob
Tyler Durden
LOL @ Commadore 64
Yes, things were easier in those days... bring back the Atari I say !
newbie777
My question would be - what are you doing in you code that you want to intentionally slow the code down by putting a pause in there.
Threading.Thread.Sleep is really a very quick and dirty way to put small pauses in an application as it will suspend the UI thread so the UI is essential dead.
There are other ways to achieve this maybe by using a timer - which will keep the UI responsive for the duration.
Let us know what you specifically trying to achieve with this delay and we can probably give you a better answer.
jena
I am guessing that you are pressing a button on the form or some other user initiated action is causing this code to run... the problem is that the work being done there is occurring in the main thread of the app, the same thread that is responsible for painting the screen to show your updates to your label text and by sleeping within it you are preventing the visual update.
In order to get around this problem you’ve got three options, spawn off a new thread to do your work, fire off some work with BackgroundWorker... or DoEvents.
In your case, the simplest method is to simply use DoEvents which pauses the execution of your code for a moment and lets the window process any outstanding messages... like those to redraw the window with a new value in the label.
In order to use it in your app we would make only a single change:
Dim g As Integer
For g = 1 To 10Application.DoEvents() ' Process outstanding messages before sleeping
System.Threading.Thread.Sleep(4000)
Label1.Text = g
Next