Re: Code executing too fast -- causes errors
- From: "Tony Jollans" <My Forename at My Surname dot com>
- Date: Sat, 18 Mar 2006 12:20:33 -0000
Thank you Jezebel,
There is clearly something fundamental I'm not understanding here, so please
bear with me.
(a) At any point in time there is a single thread running - in a single
processor environment this is by definition. This will run until it cedes
control (or, occasionally, Windows interrupts it).
(b) At the same point in time there are many other threads waiting for their
turn to run (according to priority) - again, essentially, a given.
(c) As far as I can tell from what you say, at the same point in time there
is also a queue of messages (or events) waiting to be processed. And this is
entirely separate from the threads waiting in (b) above.
So what happens when a message on the queue is processed? Might a thread get
(re)started?
If so, is it somehow queue jumping over the threads waiting in (b)
above?
If not, presumably it is added to the pool in (b) above.
If a thread doesn't get started in response to being processed from the
queue - as you are suggesting is the case with some events when a sleep is
in progress - what does happen to that message/event?
--
Enjoy,
Tony
"Jezebel" <warcrimes@xxxxxxxxxxxxxx> wrote in message
news:eeMYr5nSGHA.4752@xxxxxxxxxxxxxxxxxxxxxxx
No, you're only half understanding what's going on. DoEvents does indeedto
process the message queue -- on completion (or if the queue is empty)
control returns to the line following the DoEvents. Threads are not added
the message queue -- only events.ask
As you say, sleep suspends execution for a given duration, then resumes
provided other threads do not have higher priority at that moment. (The
sleep interval is thus a minimum, not an exact amount.)
The key difference between the two approaches is that DoEvents will permit
other actions within your own app to run (eg if the user clicks buttons,
closes forms, etc). Sleep doesn't do that: no other code within your app
will be initiated during the Sleep call.
"Tony Jollans" <My Forename at My Surname dot com> wrote in message
news:e9uQvRnSGHA.4384@xxxxxxxxxxxxxxxxxxxxxxx
Sleep will indeed do that --
-- and, as you say, avoids the risk of unexpected events getting
processed, or conversely, eliminates the need to code for all possible
events.
I didn't think I said that at all. Indeed the point of my post was to
towhether that was the case. Let me try to be clearer.
My (limited) understanding is that:
DoEvents stops processing of the current thread in order for the system
allprocess the message queue (I'm not sure of terminology but I think we
thatknow what we mean by this). It takes as long as it takes. The current
thread
is eligible for restart when the message queue has been processed. In
effect, if not in fact, the first thing that happens with DoEvents is
itthe current thread restart is added to the end of the message queue.
Sleep stops processing of the current thread for an explicit amount of
time.
During that time the system can do whatever it wants but I would expect
thatto process the message queue. In theory the current thread could restart
before the whole of the message queue had been processed but I doubt
controlWindows tries to be that clever and I suspect that the current thread
restart is added to the end of the message queue when the specified time
has
elapsed.
I don't know how Windows operates and it may have multiple queues but I
have
never seen anything which suggests so. Whenever any process cedes
areto
the operating system it must be aware of what may happen and, if
necessary,
be coded to handle it. This would seem to be as true wth Sleep as with
DoEvents.
It seems to me that, in waiting for an external process to finish,
Jonathan
is running a random (hopefully sufficient) number of DoEvents and you
elsesuggesting a random (hopefully sufficient) number of Sleeps of a random
length. Both of you have determined what works by a process of trial and
error ('testing'). What is the difference? In both cases I think there
ought
to be APIs which would be more precise but it probably isn't worth the
complexity of coding them.
--
Enjoy,
Tony
"Jezebel" <warcrimes@xxxxxxxxxxxxxx> wrote in message
news:e6XamFkSGHA.5468@xxxxxxxxxxxxxxxxxxxxxxx
Of course you sometimes need to pause a macro and wait for something
(asto
finish. Sleep will indeed do that -- that's one of its main purposes
valueopposed to DoEvents, which is specifically for processing the eventthe
queue) -- and, as you say, avoids the risk of unexpected events getting
processed, or conversely, eliminates the need to code for all possible
events.
I recently had to deal with some code that created, then despatched,
PDFs.
The problem was knowing when the PDF is created, because Doc.Printout
returns control as soon as Acrobat has finished with the Word document;
finalisation of the PDF happens asynchonously. The code used was
something
like ...
... printout
LoopCount = 0
Do
Sleep 550
Check if PDF exists: if yes, exit do
LoopCount = LoopCount + 1
If LoopCount > 5 then
err.raise .... something has gone wrong
End if
Loop
The 550 (or whatever it was) was arrived at by testing, to find the
justthat achieved the lowest aggregate time - normally the loop iterated
(foronce. (An even better solution is to use the Acrobat APIs so you *know*when
the process is complete.)
"Tony Jollans" <My Forename at My Surname dot com> wrote in message
news:%234bbAgiSGHA.1204@xxxxxxxxxxxxxxxxxxxxxxx
Hi Jezebel,
Is there a way of pausing a macro to allow another process to finish
(humour
me and accept that it might be required on occasion) without ceding
control
to the system and letting it run whatever it sees fit? Won't sleep
explicitexample) have the same effect except that it will also have an
oneThereamount of time before the process becomes eligible to be restarted.
there?is
no command that says 'selectively run other processes' or 'run other
processes except those that involve my parent' (or my children), is
--
Enjoy,
Tony
"Jezebel" <warcrimes@xxxxxxxxxxxxxx> wrote in message
news:#w5HWWiSGHA.5736@xxxxxxxxxxxxxxxxxxxxxxx
Also, please explain to me what you have against DoEvents. Your
of(unlesspost
expressing reasons said that it "is an extremely dubious practice
interferingyou're also diligently switching off every possible source of
input ...)", but when I have an example that *did* have a source
queue,input
that(the option to click the Stop button) you said that using DoEvents
in
context was the right thing to do.
The danger with DoEvents is that it processes ANY event in the
closenot
thanjust the ones you're necessarily expecting. It's not that youuse
shouldn't
it; but that you need to use a lot of care when you do -- a lot more
back.'scattering a few DoEvents around the application' implies.
To see the risk, here's a version of the example you posted a while
1. Create a form with two buttons and add this code --
Private mCharVal As Long
Public Event StopNow()
Private Sub UserForm_Initialize()
mCharVal = 65
End Sub
Private Sub CommandButton1_Click()
mCharVal = mCharVal + 1
With New Class1
Set .CallerForm = Me
.InsertChar mCharVal
End With
End Sub
Private Sub CommandButton2_Click()
RaiseEvent StopNow
End Sub
2. Create a class module with this code --
Public WithEvents CallerForm As UserForm1
Private mCancelled As Boolean
Public Sub InsertChar(CharVal As Long)
Do Until mCancelled
ActiveDocument.Range.InsertAfter Chr$(CharVal)
DoEvents
Loop
End Sub
Private Sub CallerForm_StopNow()
mCancelled = True
ActiveDocument.Range.InsertAfter "Stopping" & vbCr
End Sub
Now run the form. Click Button 1. Click it again. And Again. Now
withthecan
form by clicking the X at top right, without clicking button 2. This
is
obviously a trivial example, but you can see how sort of disasters
that
ensue from the indiscriminate use of DoEvents -- in this example, as
whileyour original version, you need to do things like disable button 1
mRunning is true, and broadcast the form terminate event so the
spawned
classes don't run for ever.
.
- Follow-Ups:
- Re: Code executing too fast -- causes errors
- From: Tony Jollans
- Re: Code executing too fast -- causes errors
- References:
- Code executing too fast -- causes errors
- From: zSplash
- Re: Code executing too fast -- causes errors
- From: Helmut Weber
- Re: Code executing too fast -- causes errors
- From: Jezebel
- Re: Code executing too fast -- causes errors
- From: Jonathan West
- Re: Code executing too fast -- causes errors
- From: Jezebel
- Re: Code executing too fast -- causes errors
- From: Jonathan West
- Re: Code executing too fast -- causes errors
- From: Jezebel
- Re: Code executing too fast -- causes errors
- From: Jonathan West
- Re: Code executing too fast -- causes errors
- From: Jezebel
- Re: Code executing too fast -- causes errors
- From: Jonathan West
- Re: Code executing too fast -- causes errors
- From: Jezebel
- Re: Code executing too fast -- causes errors
- From: Jonathan West
- Re: Code executing too fast -- causes errors
- From: Jezebel
- Re: Code executing too fast -- causes errors
- From: Tony Jollans
- Re: Code executing too fast -- causes errors
- From: Jezebel
- Re: Code executing too fast -- causes errors
- From: Tony Jollans
- Re: Code executing too fast -- causes errors
- From: Jezebel
- Code executing too fast -- causes errors
- Prev by Date: Re: Code executing too fast -- causes errors
- Next by Date: Re: Code executing too fast -- causes errors
- Previous by thread: Re: Code executing too fast -- causes errors
- Next by thread: Re: Code executing too fast -- causes errors
- Index(es):
Loading