views:

476

answers:

2

Let's say function foo() is executing. Suppose that an external event occurs, for which you have a handler. Will function foo() be interrupted so that the event handler can be executed? What is the order of execution in this situation?

A: 

This actually can be sorta tricky.

I don't really know how Flash works in this regard, but there are a couple of cases in C#, for example. I suggest you read up on how this stuff works. Also good is to break in a debugger and examine the stack that led to your event handler to get a sense for it.

Basically there's one of two scenarios going on:

  1. Like Dr_Asik says, you could be directly invoking a delegate event, which is exactly like calling a method synchronously. In this case, the normal rules about thread context-switching apply, but an event has no special properties, really. It is just a function call.

  2. You could be talking about UI Forms events. In this case, some special rules do apply. A UI event gets "posted" to the event queue, rather than being executed synchronously. So if foo() is on the "Main" UI thread, then the user presses a key while foo() is running, then the keypress is trapped by the OS and posted to the application's UI event queue. But foo() is already running, so the main thread will not stop and check that queue. Only once foo()'s entire call stack completes all the way back to the message queue checking loop will the main thread find that message, process it, and invoke its handler.

To be clear, in that last case foo() is guaranteed not to be interrupted by the UI event.

However, in case 2 there is another scenario, where foo() is not on the main UI thread. In this case, it can absolutely be interrupted, by normal context switching.

In C# it can get even trickier if you start using Control.Invoke().

This isn't Flash-specific but I hope it helps. I suspect Flash has a main thread with an event queue and a processing loop, just like C#. It's a common model that you find in at least C#, Java, and Delphi.

rice
+1. Nice recap.
Juan Pablo Califano
Not relevant to the question. The question is targeted at the flash player.
bug-a-lot
@bug-a-lot. But the model described is applicable to the flash player.
Juan Pablo Califano
+2  A: 

No, foo() will not be interrupted.

Flex is single-threaded, so foo() will continue running. Once foo() finishes and control is returned to the event loop, then the first event in the event queue will be processed.

Matt Dillard
This is correct but let me clarify just a bit. Code execution in Flash Player is single threaded. So Flex apps run on a single thread. But there are things in Flash Player which do run on separate threads, such as network IO - so that network requests don't block the UI.
James Ward
I'm afraid this is not true for all event dispatching. The event mechanism is not inherenty asynchronous. It boilds down to callbacks, really. It is true that most events dispatched by the player's API are fired asynchronously, though, like those generated by user gestures, the flash.net package, etc.
Juan Pablo Califano
Be that as it may, the answer to the user's particular question is still "No, it will not be interrupted". The user's event handler for the brand new event will still not be executed until foo() completes.
Matt Dillard
I disagree. Try dispatching an event and you'll see the handler will be called while foo is being executed. private function test():void { var dispatcher:EventDispatcher = new EventDispatcher(); dispatcher.addEventListener(Event.COMPLETE,function(e:Event):void { trace("handleComplete"); }); dispatcher.dispatchEvent(new Event(Event.COMPLETE)); trace("last line of test");}
Juan Pablo Califano
Your example is correct - my comment did not fully communicate my assertion. If some _external_ event is fired (as described by the original question), then I do not believe that event will be processed until the current routine completes. If foo() itself fires an event, then flow proceeds exactly as you describe it - the event is handled immediately on the single (main) thread.I'll admit that this is worth verifying. It would be pretty simple to create a sample app to try it out; if I have time later today, I'll do that.
Matt Dillard
For what it's worth, after some experimentation, a button press event will not interrupt another running function. All of the button clicks are queued up and handled _after_ the running function finishes running.
Matt Dillard
Matt, that's right. That's why I upvoted rice's answer. As he points out, and as I said in my first comment, some events (arguably those you use more often) are dispatched asynchronously. If by external the OP meant the flash.net API, your answer is right. Yet you could be using your own custom events or events fired by some library that is not asynchronous (I just dispatched the event directly for brevity, but this call could be buried somewhere else). In those cases, not accounting for that could lead to problems; for instance, if you re-entry the function, you could get a stack-overflow.
Juan Pablo Califano
Probably events that are explictly dispatched must also be handled synchronously in order, for the listeners, to use the event.preventDefault() feature.
Cosma Colanicchia
Except for Flash Player generated timing events all events in Flash Player are synchronous. This is why Juan's example prints "handleComplete" before "last line of test".
James Ward