Waking from sleep

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hello. I am new at this so forgive me if there is a simple answer, although
it is one I could not find.

My VB 2003 program can scan a folder, determine the size of the file it
finds, wait 30 seconds, then determine the size of the file at that point.

I wait the 30 seconds by using the Thread.Sleep method. Is there a way to
wake the sleep cycle early by having the user click a button?
 
There is.

One way to do it is set up a loop that checks to see if the button has been
clicked and take the appropriate action, thus:

Private m_clicked As Boolean = False

Sub MySleepFor30Seconds()

Private _count As Integer = 0

While Not m_clicked OrElse _count < 30
Thread.Sleep(1000)
_count += 1
Application.DoEvents
End While

End Sub

Sub MyButton_Clicked(sender As Object, e As EventArgs) Handles
MyButton.Click

m_clicked = True

End Sub

Sub MySub()

m_clicked = false

... do some stuff here

MySleepFor30Seconds()

... do some more stuff here

End Sub

Without the Application.DoEvents, the loop would be very tight so the
Application.DoEvents allows the application to catch up with other stuff
like a button being clicked.

The loop will exit after approx. 30 seconds or up to a second after the
button is clicked, whichever occurs first.

There are other ways of doing it but thay have higher degrees of complexity.

The question must be asked as to why you would want to check the size of a
file at 30 second intervals?

If it is to determine if another process has 'finished' with a file then
this way would be prone to error and there are faert easier ways of doing
such a test.
 
Stephany,

Thank you for your response.

The files I am scanning for are audio files being delivered by satellite. I
need them to finish downloading (to a linux box) before I transfer them into
my main audio system.

As I am usually willing to try new things, what are the more complicated
ways of sleeping and interrupting sleep. I would prefer a way that does not
take up much CPU cycles. That is why I was using the sleep command in the
first place.

i am not looking for you to write the code for me, but if you could point me
in the right direction I would be ever so grateful.

Thanks!
 
Without the Application.DoEvents, the loop would be very tight so the
Application.DoEvents allows the application to catch up with other stuff
like a button being clicked.

On the other hand, it means the UI will be *very* jerky during those 30
seconds. If you try resizing the window etc, it'll be horrible.
The loop will exit after approx. 30 seconds or up to a second after the
button is clicked, whichever occurs first.

There are other ways of doing it but thay have higher degrees of complexity.

Well, doing it in a different thread is *slightly* harder, but is much
nicer than restricting the UI to only processing events once a second.
 
Jon,

I thought that Stephany has well described why not to use an extra tread.

If somebody is not yet able to do such a simple solution for you and me as
Stephany gave, why than push somebody to a multithreading application only
to enable a button.

I surely would not use a multithreading application for that. The
readability of a program has for me a higher priority.

Just my thought,

Cor
 
You can create a Manual(Auto)ResetEvent and do a Wait with a time-out of 30
seconds. When the wait finishes you chaeck if it's timed out or the Event
has been set. The button click simply sets the Event. The only critical
point is the Event creation but as far as I understand what you want to do
the Thread is controlled in a very tight way so: create the Event, create
the Thread, do as described and when the Thread finishes destroy the Event
and so on.

Jochen
 
Jon is correct. Using Thread.Sleep halts the entire program execution for
the interval specified. A Windows Form is a STA (Single Threaded Apartment)
application. Everything happens on the one main thread. In her code,
Stephany puts the Thread to sleep for one second in a loop for 30 seconds.
That will produce lousy event response in the app. In addition, if an event
of the application runs another method that takes some time to execute, the
program will not resume until that method exits. This is the sort of design
that ends up becoming a nightmare experience for the user, and a maintenance
nightmare for the developer. I would think that the first priority of
writing software is usability, not readability. First, make the software
behave in the way that it should to satisfy all of the requirements
(including usability and lack of bugs); *then* make it readable and as
simple as possible.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

A watched clock never boils.

Cor Ligthert said:
Jon,

I thought that Stephany has well described why not to use an extra tread.

If somebody is not yet able to do such a simple solution for you and me as
Stephany gave, why than push somebody to a multithreading application only
to enable a button.

I surely would not use a multithreading application for that. The
readability of a program has for me a higher priority.

Just my thought,

Cor
 
Kevin,

This we don't agree, my first priority is make a program maintanable (and
running of course as it was intended by the client(s))

If that is fullfilled and it is runnng, than your priorities are in my idea
mostly as well fullfiled.

Just my thought,

Cor


Kevin Spencer said:
Jon is correct. Using Thread.Sleep halts the entire program execution for
the interval specified. A Windows Form is a STA (Single Threaded
Apartment) application. Everything happens on the one main thread. In her
code, Stephany puts the Thread to sleep for one second in a loop for 30
seconds. That will produce lousy event response in the app. In addition,
if an event of the application runs another method that takes some time to
execute, the program will not resume until that method exits. This is the
sort of design that ends up becoming a nightmare experience for the user,
and a maintenance nightmare for the developer. I would think that the
first priority of writing software is usability, not readability. First,
make the software behave in the way that it should to satisfy all of the
requirements (including usability and lack of bugs); *then* make it
readable and as simple as possible.

--
HTH,

Kevin Spencer
Microsoft MVP
Software Composer
http://unclechutney.blogspot.com

A watched clock never boils.
 
JackCoke,

Can you describe in a little more detail about what behavior you're
wanting? Do you need to check the size of a file every 30 seconds?
When the user clicks a button should the check occur immediately?
That's how interpreted your post. If that's the case use the
System.Windows.Forms.Timer to raise an event every 30 seconds that
checks the size of the file. And in the button click event do the
check there as well.

Brian
 
Cor Ligthert said:
I thought that Stephany has well described why not to use an extra tread.

Not really - because he didn't explain what the consequence of his
solution was: that the UI is unresponsive except for once per second.
If somebody is not yet able to do such a simple solution for you and me as
Stephany gave, why than push somebody to a multithreading application only
to enable a button.

I surely would not use a multithreading application for that. The
readability of a program has for me a higher priority.

Thinking about it, a System.Windows.Forms.Timer would probably be the
best solution for this situation - *if* there's not much work to do. If
there's a fair amount of work to do, I'd still use a separate thread.
It's really not that complicated, unless you don't know threading at
all already - and if you don't, it's worth learning anyway. I doubt
that any professional developer is going to last very long without
understanding the basics of threading these days.
 
Cor Ligthert said:
This we don't agree, my first priority is make a program maintanable (and
running of course as it was intended by the client(s))

The bit in brackets is important though. Here's a short but complete
program which shows what happens when the main thread is sent to sleep
repeatedly. Run it, resize and reposition the form a few times, then
click the button and try resizing/repositioning/etc. It's horrible - it
looks completely unprofessional for a UI to be unresponsive in that
way, IMO.


using System;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;

class Test
{
static void Main()
{
Form f = new Form();
f.Size = new Size (200, 200);

Button b = new Button();
b.Click += GoSlow;
b.Text = "Click me";

f.Controls.Add (b);
Application.Run(f);
}

static void GoSlow(object o, EventArgs e)
{
while (true)
{
Application.DoEvents();
Thread.Sleep(1000);
}
}
}
 
Thanks everybody.

Brian, your interpertation was correct. I will use the system timer function
to write text on a button that will show the time before the next scan. This
will allow me to move forward with the process if the button is clicked.
--
Thanks for your help.
(e-mail address removed)
My email address can be determined by reading everything befort the at symbol.


Brian Gideon said:
JackCoke,

Can you describe in a little more detail about what behavior you're
wanting? Do you need to check the size of a file every 30 seconds?
When the user clicks a button should the check occur immediately?
That's how interpreted your post. If that's the case use the
System.Windows.Forms.Timer to raise an event every 30 seconds that
checks the size of the file. And in the button click event do the
check there as well.

Brian
 
I aggree entirely Jon, however, the OP was not asking about anything to do
with unresponsive UI's or the need to make sure that there were no
performance impacts.

I was doing nothing more than demonstrating one way of 'interrupting' a
'long' sleep cycle.
 
FYI Jon, this 'he' is very much a 'she' :)


Jon Skeet said:
Not really - because he didn't explain what the consequence of his
solution was: that the UI is unresponsive except for once per second.


Thinking about it, a System.Windows.Forms.Timer would probably be the
best solution for this situation - *if* there's not much work to do. If
there's a fair amount of work to do, I'd still use a separate thread.
It's really not that complicated, unless you don't know threading at
all already - and if you don't, it's worth learning anyway. I doubt
that any professional developer is going to last very long without
understanding the basics of threading these days.
 
OK, time for System.IO 101.

When whatever is creating the file on disk, creates the file, it opens it
for output, writes data to the file and then it closes the file.

Although, under some circumstances you can open the file from another
process, you can, generally, not carry out any action requiring exclusive
access until the creating process releases the file.

Once you have established that the file exists, the next step would be to
see if you can open the file for exclusive use. If that succeeds then the
creating process has finished with the file and you can do what you want
with it. It it fails then you need to try again later. This is tidier than
checking the file size for example.

As others have pointed out there are a number of mechanisms you can use for
'timing' your checks without resorting to the Thread.Sleep method.
 
Stephany Young said:
I aggree entirely Jon, however, the OP was not asking about anything to do
with unresponsive UI's or the need to make sure that there were no
performance impacts.

I was doing nothing more than demonstrating one way of 'interrupting' a
'long' sleep cycle.

But why do that by recommending something that will give rise to
another problem? I don't believe many people would view a UI that's
that unresponsive as being an acceptable solution.

Admittedly my own suggestion of using a monitor or ResetEvent wasn't
the best solution either - the best solution is to use a
System.Windows.Forms.Timer, which has the best of pretty much all
worlds.
 
Hello Stephany,

Steph is absolutely right. You should open the file for exclusive read/write
to determin when the downloader is done with it. Your satelite may hiccup
for 30 seconds, in which case your scanning method would fail.

-Boo
 
Without attempting to appear pedantic, I can't see where I recommended
anything.

I merely demonstrated ONE way of doing something. At the same time I also
said, although I failed to eleborate, that there were other ways of doing
it, but I certainly did not recommend using any particular methodology.

We all know that the framework often provides us with a number of similar
methods for doing the same thing and that while one method is quite suitable
in a certain scenario, another method is better suited to a different
scenario.

We also know that everybody has their own view of what works best for them
in certain situations, and, although I don't always succeed, I do try to not
present an idea, air-code or whatever as the only way of doing something or
even the best way, but rather in a way that demonstrates the point I am
attempting to make at the time.
 
Back
Top