views:

543

answers:

4

Hello

I googled for this and read some threads here, but I haven't found a simple way to have a VB.Net application sleep for a little while and still keep the application responsive:

Imports System.Net
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Threading.Thread

[...]

''#How to keep screen frop freezing?
While True
  ListBox1.Items.Clear()

  ListBox1.Items.Add("blah")

  ''#Not much difference
  ListBox1.Refresh()

  ''#Wait 1mn
  Sleep(60000)
End While

Is there really no simple, non-blocking solution to have a VB.Net application wait for a few seconds?

Thank you.

+5  A: 

Is this WinForms or WPF?

If it's WinForms you could just use a timer instead of a while loop. Then your app would still be responsive and raise events.

In WPF I think you would have to make your own timer based on the DispatchTimer class.

smoore
Aren't there timers in WPF also?
Dennis Palmer
I just opened a project really quick and didn't see any Timer controls in the designer, so there very well might be, I've just never needed to use one in WPF. A quick search on google makes me think though that it's not available (http://social.msdn.microsoft.com/forums/en-US/wpf/thread/aaffea95-e735-492d-bd8a-2fdf7099a936/).
smoore
+1  A: 

The Timer suggestion is really the best way to do it. But if DoEvents still works (I haven't done VB since 5.0), you can do this:

For i = 0 To 600
    DoEvents
    Sleep(100)
Next

This would do 600 sleeps of .1 second each, with a DoEvents between each to handle current events. The .1 second should be a good tradeoff between responsiveness (events get handled within .1 second) and CPU consumtion (do this too fast and your app will start consuming a significant amount of CPU time even while waiting).

Wim
Dear downvoter, while I respectfully accept your downvote, would you consider leaving a comment with which I could improve my answer? Thanks.
Wim
I don't know why this was downvoted either. The functions are called Application.DoEvents and Thread.Sleep in .NET, but anyone with an up to date MSDN would have found that out. It should be pointed out that DoEvents can lead to all kinds of weird behavior (e.g. if the form is closed while the function is running or if DoEvents calls the same function again.) But you did say that it's not the ideal way to do that.
nikie
I'm not the downvoter, but DoEvents is not good practice. It causes issues if the method is not correctly written to account for re-entry.
Joel Coehoorn
A: 

(I'll answer to myself since comments don't accept code)

By default, the Timer will trigger after the time has elapsed. Is there a way to force it run right when the application start instead of waiting for the Timer to strike? I couldn't call the Timer1_Tick() event:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    ''#Check every minute
    Timer1.Interval = 60000
    Timer1.Enabled = True
    ''#Timer1_Tick()
    Timer1.Start()

End Sub
OverTheRainbow
You can edit/update your question, that should have more visibility than a new answer with 0 upvotes.
Wim
Thanks for the tip.
OverTheRainbow
A: 
Public Sub ResponsiveSleep(ByRef iMilliSeconds As Integer)
    Dim i As Integer, iHalfSeconds As Integer = iMilliSeconds / 500
    For i = 1 To iHalfSeconds
        Threading.Thread.Sleep(500) : Application.DoEvents()
    Next i
End Sub

Call ResponsiveSleep to pause a particular piece of code whilst keeping the application fairly responsive. To make the application more responsive iHalfSeconds could be modified to tenths or hundredths of a second