[Lazarus] Lazarus and Application.ProcessMessages

Lukasz Sokol el.es.cr at gmail.com
Mon Dec 8 11:46:50 CET 2014


On 05/12/14 13:53, Michael Schnell wrote:
> On 12/04/2014 04:24 PM, Lukasz Sokol wrote:
>> Or e.g. I run FindFirst/FindNext loop over a large number of files,
>> or even if I delegate reading of a file to another procedure, still
>> takes time while nothing else can happen... (although /that/
>> actually I can imagine doing in a thread). Then such
>> Application.ProcessMessages is about the only option ?
> 
> A long winding loop (such as "FindNext" freezes the GUI and all
> TTimers if you don't include ProcessMessages.

Yes. 

> 
> If doing the loop in a Thread you can send status messages to the
> main (GUI) thread by means of TThread.Queue or
> Application.QueueAsyncCall. (You do know that you can't access the
> GUI from a worker thread.)
> 

Yes. 

These are 'technicalities' of inter-thread communications 
more specifically thread-to-mainthread communication)
that can be figured out relatively easily and found when you need them.

Let's assume we have a procedure that is executed once per the window 
being created (or shown) : first we read a file list into a list of
file names, read some attributes (e.g. file date) into a string list
and put it into a TMemo or some TFileList; then we read a file list with a slightly different
mask and read their names/dates and put it into another TMemo or TFileList;
and finally, we read yet another set of files and put names/dates  into a memo or filelist.

(as it would be, say a result of having input files created by external program, fed to another external program,
and another external processing program called on the output of the second one, so we have 3 sets of files:
input, itermediate, output.)

Let's also assume that the files need to be read in particular order
(as what we want to read in second and third indexing may depend on
 what we read in the first and second one).

So we create TThread workers for indexing1, indexing2 and indexing3,
they return TStringList's to us, we call some string-list processing procedures
on their results [which don't take as much time to process so they are
called in main thread context with ProcessMessages in their loops, but if they
were to be more 'complex' and time-consuming, they would be put into threads of themselves too]
and give certain parameters to the next indexing' (or worker) thread to work with.

What I mean is, when I have a long-winding [long-timed] sequence of worker threads like this,
written inside of an 'OnShow' or 'OnClick', I want to have the whole of
the sequence written in ONE logical flow, inside one procedure code block...
right ? (and say it's written so that one procedure is not longer than 3 screens vertically ;)
 and has no more than 3 levels of nesting too;) and most importantly
to use same local variables (locally created string lists, for example).

(ok I know this probably is an 'obvious' thing for any formally trained programmer
of just about any language out there... ;) but I ain't one... )

The advice to OP was, fire up a thread (or TTimer) for such long processing loops 
as the 'last thing' in the sequence, then continue the flow of whatever you need to do
in another procedure, called after the thread/ttimer is done...

which I argue is not optimal /to humans/ as a) it disturbs reading order and b) disallows
the portions of the logically close code from using same local variables
and c) if put as subroutines, disturbs reading flow even worse.


> -Michael
> 

el es





More information about the Lazarus mailing list