While poking around in the Flex SDK source code I came across an undocumented class called AsyncDispacther under \Flex Builder 3 Plug-in\sdks\3.2.0\frameworks\projects\rpc\src\mx\rpc and it reminded me of some of the tricks we used to use before Flash Player 9 to overcome problems we encountered.
AsyncDispatcher is a way to delay the calling of a method for a specific time interval. Its constructor is below.
public function AsyncDispatcher(method:Function, args:Array, delay:Number)
{
super();
_method = method;
_args = args;
_timer = new Timer(delay);
_timer.addEventListener(TimerEvent.TIMER, timerEventHandler);
_timer.start();
}
It takes as parameters a function, the functions arguments and a delay in milliseconds. It then creates a Timer and waits the specified delay to call the function in the timerEventHandler method.
Back before Flash Player 9 when the Flash Player wasn’t as fast you could see performance degradation if you tried to do too much in a single frame. It was common in those days to use tricks like this to delay processing if for instance your UI was rendering or an animation was running. This is basically what the callLater method in UIComponent does. It delays a method call for one frame. But what if you are not extending UIComponent? This class would let you do the same thing from say a model class or a responder class. This class could be used in much the same way to delay invoking some method until it was safe to do so.
One improvement I would make to this class would be the ability to call the method a specific number of times or indefinitely. Since Timer takes a ‘repeatCount’ parameter this would be as simple as passing an additional argument in the constructor. This ‘repeatCount’ parameter could default to 1. I worked on a project long before before WebORB was free and for a client that didn’t want to pay $10,000 per CPU for it and before the Flex SDK was open source so the source for classes like this were not included. We needed a way to update all open clients whenever a change was made to the database. I created a class very similar to this to call a script on the server every 4 minutes to check for updates. It worked surprisingly well.
As a note - because this class is undocumented doesn’t mean you shouldn’t use it. It is used by the RPC classes in the framework.
Comments
prevent stack overflow
I also found this trying to track down some mystery timer that appears in my runtime with a delay of 1500 that I never created. I have a different theory for what AsyncDispatcher is for.
For various design reasons, my program performs iteration on elements mediated by event dispatches. Every time through the loop, the event and the function calls that it initiates get added to the stack. The stack only unwinds when the iteration is done. This works fine for small numbers of iterations, but with > 500 objects or so I was getting stack overflows. I think this kind of situation is a consequence of Flash being single-threaded.
The solution I found is to break the chain by creating a timer. Every time through the loop the timer gets started, which lets the control flow return and unwind the stack back to the GUI event that triggered it. Then when the timer event gets handled we do one iteration and launch the timer again.
I would guess that AsyncDispatcher serves this function without you having to create your own timer and handler.
-Eric Saund
saund@parc.com
Re: prevent stack overflow
I used to do the same thing before Flash Player 9. Back then the Flash Player was slow and if you had a loop that was > 500 iterations you would have to break out of the loop in order for the Flash Player to release memory. You could then continue your loop. Also - I know in some contexts the Flash Player is multi-threaded (the features list in this article mention it - http://www.kaourantin.net/2007/06/flash-player-update-3-beta-1.html).
Re: prevent stack overflow
This is clever, but how is it different from just calling setTimeout directly? It seems like it even introduces some extra overhead (since you creating a new Timer object, registering an event handler, having your event handler called, calling the original function).
Re: prevent stack overflow
Yes you could use setTimeout although the documentation for setTimeout actually recommends a Timer over setTimeout but they are specific as to why. I suspect it is because under the covers setTimeout creates a Timer anyways. IMHO AsyncDispatcher is a cleaner approach as it encapsulates the timer in a seperate class and is reusable.