如何增加延时以在Actionscript中处理超过15秒?

时间:2019-05-20 16:01:11

标签: loops actionscript-3 time while-loop actionscript

所以我有以下脚本来获取数组的所有组合: '''

var value = new Array(40)
for (var i=0;i<value.length;i++){
    value[i]=i;
}
var comb_list = getAllComb(value,24);
trace(comb_list)
function getAllComb(values:Array, r:int):Array{
    var n = values.length;
    var result = new Array();
    var a = new Array(r);

    // initialize first combination
    for (var i = 0; i < r; i++) {
        a[i] = i;
    }

    i = r - 1; // Index to keep track of maximum unsaturated element in array
    // a[0] can only be n-r+1 exactly once - our termination condition!
    var count = 0;
    while (a[0] < n - r + 1) {
        // If outer elements are saturated, keep decrementing i till you find unsaturated element
        while (i > 0 && a[i] == n - r + i) {
            i--;
        }
        result.push(a.slice())// pseudo-code to print array as space separated numbers
        count++;
        a[i]++;
        // Reset each outer element to prev element + 1
        while (i < r - 1) {
            a[i + 1] = a[i] + 1;
            i++;
        }
    }
    return result;
}

'''

运行上述脚本会得到我的帮助

错误:错误#1502:脚本执行的时间超过了默认超时时间15秒。

如何增加每经过14秒的时间延迟,以便我可以运行脚本?因此,经过14秒后,程序将等待50毫秒,然后继续。

任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:2)

因此,有一个简单的(很好的例子)示例,说明如何将繁重的计算部分与主线程分开,以便主线程(还处理UI和诸如用户输入之类的外部事件)可以平稳运行,同时能够读取引擎盖下的进度和大量计算结果。它也以单个类的形式出现,这可能有点令人困惑(直到您了解它是如何工作的),但仍然易于处理和修改。

尽管后台AVM遵循相同的执行流程(代码执行>图形渲染>代码执行>图形渲染>依此类推),但没有要渲染的图形,因此无需限制代码执行时间。结果, Worker 线程不受15秒限制,从而以某种方式解决了问题。

package
{
    import flash.events.Event;
    import flash.display.Sprite;
    import flash.utils.ByteArray;

    import flash.concurrent.Mutex;

    import flash.system.Worker;
    import flash.system.WorkerDomain;

    public class MultiThreading extends Sprite
    {
        // These variables are needed by both the main and
        // subservient threads and will actually point to
        // the very same object instances, though from
        // the different sides of this application.
        private var B:ByteArray;
        private var W:Worker;
        private var M:Mutex;

        // Constructor method.
        public function MultiThreading() 
        {
            super();

            // This property is 'true' for the main thread
            // and 'false' for any Worker instance created.
            if (Worker.current.isPrimordial)
            {
                prepareProgress();
                prepareThread();
                startMain();
            }
            else
            {
                startWorker();
            }
        }

        // *** THE MAIN THREAD *** //

        private var P:Sprite;
        private var F:Sprite;

        // Prepares the progress bar graphics.
        private function prepareProgress():void
        {
            F = new Sprite;
            P = new Sprite;

            P.graphics.beginFill(0x0000FF);
            P.graphics.drawRect(0, 0, 100, 10);
            P.graphics.endFill();
            P.scaleX = 0;

            F.graphics.lineStyle(0, 0x000000);
            F.graphics.drawRect(0, 0, 100, 10);

            F.x = 10;
            F.y = 10;
            P.x = 10;
            P.y = 10;

            addChild(P);
            addChild(F);
        }

        // Prepares the subservient thread and shares
        // the ByteArray (the way to pass messages)
        // and the Mutex (the way to access the shared
        // resources in a multi-thread environment
        // without stepping on each others' toes).
        private function prepareThread():void
        {
            M = new Mutex;
            B = new ByteArray;
            B.shareable = true;
            B.writeObject(incomingMessage);

            W = WorkerDomain.current.createWorker(loaderInfo.bytes);
            W.setSharedProperty("message", B);
            W.setSharedProperty("lock", M);
        }

        // Starts listening to what the background thread has to say
        // and also starts the background thread itself.
        private function startMain():void
        {
            addEventListener(Event.ENTER_FRAME, onFrame);

            W.start();
        }

        private var incomingMessage:Object = {ready:0, total:100};

        private function onFrame(e:Event):void
        {
            // This method runs only 20-25 times a second.
            // We need to set a lock on the Mutex in order
            // to read the shared data without any risks
            // of colliding with the thread writing the
            // same data at the same moment of time.
            M.lock();

            B.position = 0;
            incomingMessage = B.readObject();

            M.unlock();

            // Display the current data.
            P.scaleX = incomingMessage.ready / incomingMessage.total;
            P.alpha = 1 - 0.5 * P.scaleX;

            // Kill the thread if it signalled it is done calculating.
            if (incomingMessage.terminate)
            {
                removeEventListener(Event.ENTER_FRAME, onFrame);

                W.terminate();

                B.clear();

                B = null;
                M = null;
                W = null;
            }
        }

        // *** THE BACKGROUND WORKER PART *** //

        // I will use the same W, M and B variables to refer
        // the same Worker, Mutex and ByteArray respectively,
        // but you must keep in mind that this part of the code
        // runs on a different virtual machine, so it is the
        // different class instance thus its fields are not
        // the same quite as well.

        // Initialization.
        private function startWorker():void
        {
            W = Worker.current;
            M = W.getSharedProperty("lock");
            B = W.getSharedProperty("message");

            // Before starting the heavy calculations loop
            // we need to release the main thread which is
            // presently on W.start() instruction. I tried
            // without it and it gives a huuuge lag before
            // actually proceeding to intended work.
            addEventListener(Event.ENTER_FRAME, onWorking);
        }

        private function onWorking(e:Event):void
        {
            removeEventListener(Event.ENTER_FRAME, onWorking);

            var aMax:int = 10000000;

            // Very very long loop which might run
            // over the course of several seconds.
            for (var i:int = 0; i < aMax; i++)
            {
                // This subservient thread does not actually need to
                // write its status every single loop, so lets don't
                // explicitly lock the shared resources for they
                // might be in use by the main thread.
                if (M.tryLock())
                {
                    B.position = 0;
                    B.writeObject({ready:i, total:aMax});

                    M.unlock();
                }
            }

            // Let's notify the main thread that
            // the calculations are finally done.
            M.lock();

            B.position = 0;
            B.writeObject({ready:i, total:aMax, terminate:true});

            M.unlock();

            // Release the used variables and prepare to be terminated.
            M = null;
            B = null;
            W = null;
        }
    }
}

答案 1 :(得分:1)

该错误与您的脚本是否需要时间无关,问题在于您的while循环使您的脚本无响应超过15秒,从而触发了脚本超时错误。 “动作脚本”仅允许15秒执行脚本。

您的第一个while循环看起来有问题,我不清楚a [0]的值如何更改以结束循环。在循环中添加一个中断,或确保条件发生变化以允许循环结束,然后应该解决问题。如果只在发现不饱和值之后才运行一次continue语句,则还可以考虑将它们添加到嵌入式while循环中。

就个人而言,由于您使用的是ActionScript,因此建议您使用对象和侦听器进行值更改,而不是遍历数组以检查更改。

您还可以为while循环添加手动超时,但是需要包括逻辑使其可以从中断处继续。

//Set timer to 14 seconds
timeout = getTimer() + 14000;
while(true && timeout > getTimer()){
    trace("No Error");
}

答案 2 :(得分:1)

如果使用的是Adobe Animate(Flash),则可以从“发布”设置页面更改“脚本时间限制”。 enter image description here