🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.pascal.delphi.misc
3 messages
3 total messages Started by Sundial Services Mon, 06 Dec 1999 00:00
TechTips: Avoiding unavoidable recursion in event-handlers ...
#71
Author: Sundial Services
Date: Mon, 06 Dec 1999 00:00
74 lines
4342 bytes
Delphi works its apparent magic by a series of event-handlers.  Every
component, visible and non-visible, has a series of event-properties
which allow you to intercept these events as they occur.  Other key
Delphi features such as the "inherited" statement, the ability to create
subclassed descendents of toolbar components and even of other forms in
your application, are the key to Delphi's power -- but also put many of
the interactions that DO take place in your application quite out of
sight.  This can make them tough to debug sometimes.

To make a long TechTip short, however, let's focus on one of the more
troublesome problems:  recursion.  This is where something that you are
doing inside an event-handler might cause the same event to occur.  This
causes your event-handler to be entered recursively (which Delphi
certainly supports...), whereupon the nefarious cycle begins again until
the stack is blown and the application (or the system) crashes.

Whether or not recursion will occur in your case depends entirely upon
you and what you're doing.  The question before the house is simply, how
can we keep it from getting in the way?  The answer is simple.

(1) Define a boolean variable, in the "private" section of your class
declaration.  Let's call it "recursionLock."  You might have several of
these, depending upon how many potentially-recursive paths you have. 
Notice that this must not be a *local* variable, nor should it be
*global.*

(2) Now for your method-code.  Modify it like this:

	method ...
	...
	begin
	  if RecursionLock then exit;
          try
	    RecursionLock := true;
	    << original method code goes here >>
	  finally
	    RecursionLock := false;
	  end;
	end;

(3) You know from the outset that "recursionLock" will be initially
false, because every byte of a new object is initialized to zero (false)
by Delphi.  So you don't have to initialize it that way.

(4) Now, the first instance of the method will find the lock is open, go
right inside, and shut the lock behind him.  Any other recursion through
the routine will find the lock is closed and simply exit.  The recursion
takes place, as it must, but it does no harm.

(5) The "try..finally" block is essential.  It guarantees that, even if
an exception occurs, and even if you "exit" or "break" out of the block,
the "finally" part will be executed.

(6) Naturally, you must do nothing before the "try" part, or in the
"finally" part, that would cause recursion.


This technique is useful for other things, too -- like "CalcFields"
routines.  Calculated fields are wonderful things but they go off like
your next door neighbor's car-alarm ... anytime day or night, even when
you don't want them to or need them to.  (Really you only need a
calculated field to go off when you're about to display the value
someplace.)  A "CalcFields" routine can examine the flag to realize when
it's got a "phony call," and simply exit.  This routine would not set
the flag, nor reset it, but simply notice when it is currently set.

HTH!  :-)
 
----------------------------------------------------------------------
Sundial Services :: Scottsdale, AZ (USA) :: (480) 946-8259
mailto:info@sundialservices.com  (PGP public key available.)
> High-speed, script-driven, table repair/support for Paradox/BDE...
> ChimneySweep{tm}:  "Click click, it's fixed!" {tm}
> http://www.sundialservices.com/cs3web.htm
Re: Sv: TechTips: Avoiding unavoidable recursion in event-handlers ...
#70
Author: Michael Winter
Date: Mon, 06 Dec 1999 00:00
10 lines
1316 bytes
Finn Tolderlund schrieb:
> 
> It is much simpler just to set the eventhandler to nil upon entry and
> restore it upon exit.
> That way there is no need to define any variables.

It depends. Think about an event handler which is triggered by more than
one object. Or even by more than one event of an object.

-Michael
Sv: TechTips: Avoiding unavoidable recursion in event-handlers ...
#72
Author: Finn Tolderlund
Date: Mon, 06 Dec 1999 00:00
27 lines
1878 bytes
It is much simpler just to set the eventhandler to nil upon entry and
restore it upon exit.
That way there is no need to define any variables.

Finn Tolderlund

Sundial Services <info@sundialservices.com> skrev i en
nyhedsmeddelelse:384BDF64.10D8@sundialservices.com...
> (1) Define a boolean variable, in the "private" section of your class
> declaration.  Let's call it "recursionLock."  You might have several of
> these, depending upon how many potentially-recursive paths you have.
> Notice that this must not be a *local* variable, nor should it be
> *global.*
>
> (2) Now for your method-code.  Modify it like this:
>
> method ...
> ...
> begin
>   if RecursionLock then exit;
>           try
>     RecursionLock := true;
>     << original method code goes here >>
>   finally
>     RecursionLock := false;
>   end;
> end;
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads