0

I want to upload images with multiple URLLOADER s,so that i could save the time when waiting for the COMPLETE_EVENT.

Sometimes it could get blocked,and it does not give a completion event, does not give a security error, does not give a status event and does not throw an exception. It simply never fires any event at all.

private const RO_NUMBER:int = 2;
private var roPool:Array = new Array();

public function init():void {

        for (var i:int = 0; i < RO_NUMBER; i++) {

           loader:URLLoader = new URLLoader();
           loader.dataFormat = URLLoaderDataFormat.TEXT;
           loader.addEventListener(Event.OPEN, onStartUpload);
           loader.addEventListener(Event.COMPLETE, completeHandler);
           loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
           loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
           loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

           roPool.push(loader);
        }
    }

public function startUpload(pictures:ArrayList):void {
        _pictures.addAll(pictures);
        init();
        if (getExternalInfo()) {
            for (var i:int = 0; i < RO_NUMBER; i++) {
                var loader = roPool.pop();

                loader.load(getRequest());
            }
        } else {
            onUploadFinish();
        }
    }

the load operation is asynchronous and single thread .why could this get blocked?

wa7chen
  • 1
  • 2

2 Answers2

1

Answer based on this version:
https://stackoverflow.com/revisions/7466248/1

From what I can see in your code, you're using the same instance of URLLoader in each iteration of your loop.

You'll need to create a new instance of URLLoader and add that into your array roPool, because at the moment you're doing the same thing repeatedly to the same URLLoader.

public function init():void
{
    for(var i:int = 0; i<RO_NUMBER; i++)
    {
        var ldr:URLLoader = new URLLoader();

        ldr.dataFormat = URLLoaderDataFormat.TEXT;
        ldr.addEventListener(Event.OPEN, onStartUpload);
        ldr.addEventListener(Event.COMPLETE, completeHandler);
        ldr.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
        ldr.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
        ldr.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

        roPool.push(ldr);
    }
}

New answer:

Try making a queue and only having one instance of URLLoader at a time, rough example:

Class:

package
{
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.events.Event;

    public class LoadQueuer extends Object
    {
        // Queue
        private var _queue:Array = [];

        /**
         * Standard load
         * @param req Instance of URLRequest
         */
        public function queue(loader:URLLoader, request:URLRequest):void
        {
            _queue.push({LOADER: loader, REQUEST: request});
            _next();
        }

        /**
         * Loads next loader in _queue
         */
        private function _next():void
        {
            if(_queue.length > 0)
            {
                var info:Object = _queue.pop();

                var loader:URLLoader = URLLoader(info.LOADER);

                loader.load(
                    URLRequest(info.REQUEST)
                );

                loader.addEventListener(Event.COMPLETE, _complete);
            }
        }

        /**
         * ..
         * Event.COMPLETE
         */
        private function _complete(e:Event):void
        {
            var loader:URLLoader = URLLoader(e.target);
            loader.removeEventListener(Event.COMPLETE, _complete);

            trace(loader.data);

            _next();
        }
    }
}

Example use:

var list:Array = [
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php",
    "http://projectavian.com/test.php"
];

var lc:LoadQueuer = new LoadQueuer();

for each(var i:String in list)
{
    lc.queue(
        new URLLoader(),
        new URLRequest(i)
    );
}

Hope this helps you.

Community
  • 1
  • 1
Marty
  • 39,033
  • 19
  • 93
  • 162
1

Found this:

A browser usually allows only 2 simultaneous HTTP KeepAlive connections. The other connections are postponed.


For this scenario, best practice dictates using a single instance of URLLoader; chances are you're getting blocked somewhere by competing calls. As well, you might try using a simple flag to detect whether your loader's busy on an existing call before making another one; here's a working example using a single loader making requests every five seconds, showing both the single loader and the "isOpen" check:

Try this answer: URLLoader gets stuck when polling

Community
  • 1
  • 1
Mattias
  • 3,907
  • 4
  • 28
  • 50
  • Nice, I normally queue my URLLoaders in an array and remove/load the first thing in the queue on each Event.COMPLETE. – Marty Sep 19 '11 at 07:50