Async APIs and Garbage Collection

In my previous post I made a point of calling out the need to keep a reference on a FileStream object while waiting for an asynchronous operation, such as a read, to complete. Although this behavior is not necessarily intuitive, I thought it at least had the advantage of being consistent across the Flash and AIR APIs.

It turns out I was incorrect about this and that some related objects, such as URLStream, are guaranteed to remain live until after they have dispatched a completion event. This behavior is both more useful and more intuitive; after all, it only makes sense that there would be a reference to the URLStream somewhere in the system while it’s hanging around receiving data.

Futhermore, a particular case of the must-keep-a-reference-for-yourself mode APIs was causing a lot of grief: File.browseForDirectory() and company. You see, garbage collection doesn’t happen immediately. So even though you might not have a reference to an object to keep it alive, it can still hang around for a while if the collector hasn’t gotten around to cleaning it up. But the File.browse…() methods, being interactive, tend to take much longer to complete. That pretty much guarantees that the collector is going to run, find them, and wham–no more browse dialog.

After discussing this internally, we’ve decided the URLStream behavior should be used wherever possible. It will apply to File, FileStream, and the like. The one case that we’re unlikely to change is Timer, and that’s out of concern for existing use of the API. (Timer is a Flash API and has shipped in a final release; we don’t have as much flexibility in changing it was we do the AIR APIs while we’re still pre-1.0.)

I’m confident that this change will eliminate a whole lot of hard-to-find bugs from a whole lot of applications.