Yeah, may be. Currently I've replaced the ProcessMessages with MainForm.Update which resolves the issue well enough I think.
I don't want to make major changes as it's very stable now apart from this issue. Thanks anyway. -----Original Message----- From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On Behalf Of Paul Heinz Sent: Wednesday, 3 August 2011 12:39 p.m. To: NZ Borland Developers Group - Delphi List Subject: Re: [DUG] Why does this hang? 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 :-) Cheers, Paul. _______________________________________________ NZ Borland Developers Group - Delphi mailing list Post: email@example.com Admin: http://delphi.org.nz/mailman/listinfo/delphi Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: unsubscribe _______________________________________________ NZ Borland Developers Group - Delphi mailing list Post: firstname.lastname@example.org Admin: http://delphi.org.nz/mailman/listinfo/delphi Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: unsubscribe