Ross wrote: 

> The Timer.OnExecute I mentioned being run inside the loop 
> excludes some of the functions that are normally executed by 
> the timer, as these functions can not execute while we are 
> waiting on the thread.
> The timer cannot be idle.  It's not just updating the UI but 
> doing some other important work that is necessary to continue.
> I should probably mention that it's a media player with a VU 
> meter that needs updating continuously and elapsed/remaining 
> times etc.  The other thread is doing the actual playing of 
> the audio files.

Ah OK. I wondered if this was all something media/steaming related.
The slight unreliability of WM_TIMER messages is probaby fine for
updating that.
> The wait needs to occur when sending a command to the thread 
> to preload a track, or start playing, etc.  On occasions, a 
> procedure in the main app involves issuing several commands 
> which need to occur sequentially, hence the need to wait 
> until one command is complete.  Normally this wait is less 
> than 1 second, but it's still long enough at times to get a 
> modal dialog opened within the ProcessMessages loop, and then 
> this function hangs.
> It's been like this for years, but the occasional user comes 
> across the problem and the media player stops, generally 
> between tracks, when opening a modal dialog at the wrong moment.
> Preventing a modal window from opening while in this loop 
> seems to be the only solution.  The messages I was trying to 
> avoid processing were mouse clicks and keyboard keys.
> Any other ideas how to resolve this?

Hrmm.. Would adding a command or work queue abstraction better solve
your sequencing problem?
i.e. all 'hand-off' from the main UI thread to the streamer/working
thread is done via a queue of commands objects which that thread
processes sequentially, picking up the next one (if it exists) after it
finishes. You'd need to ensure the command queue datastructure is
thread-safe of course, but a simple TThreadList of command objects would
be fine. Assuming there are different 'kinds' of work, falls nicely onto
an inheritance hierachy of command objects with a virtual 'Execute'
method and the necessary parameter passed in their constructors.

This will completely decouple the work sequencing from the main UI
thread message loop. The main UI thread may need some ability to cancel
previously submitted commands or indicate a completion handler on
submission so as to sync the UI with the work state but that is all just
'a small matter of programming' :-)

Alternatively, it is possible to either code up your own version of
Application.ProcessMessages (or tweak the Forms.pas version as we have)
to pass an appropriate PM_QS_ mask to PeekMessage so as dispatch
everything _except_ input events (mouse or keyboard) and thus prevent UI
activity whilst 'sequencing'.

But design-wise, I think decoupling the main thread/worker thread
sequencing via a work queue is far cleaner. Still, it's your app :-)


NZ Borland Developers Group - Delphi mailing list
Unsubscribe: send an email to with Subject: 

Reply via email to