Как добавить задержку для обработки более 15 секунд в Actionscript? - PullRequest
1 голос
/ 20 мая 2019

Итак, у меня есть следующий скрипт для получения всех комбинаций массива: '' '

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 ]

3 голосов
/ 21 мая 2019

Итак, есть простой (ну, в значительной степени) и рабочий пример того, как отделить тяжелую часть вычислений от основного потока, чтобы основной поток (который также обрабатывает пользовательский интерфейс и внешние события, такие как ввод данных пользователем) работал бы гладко,будучи в состоянии прочитать прогресс и результаты тяжелых расчетов, идущих под капотом.Он также представлен в виде отдельного класса, это может немного сбивать с толку (пока вы не поймете, как это работает), но все еще легко обрабатывать и изменять.

Хотя фоновый 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 голос
/ 22 мая 2019

Если вы использовали Adobe Animate (Flash), вы можете изменить «Ограничение времени скрипта» на странице настроек публикации.enter image description here

1 голос
/ 20 мая 2019

Ошибка не связана с тем, что вашему сценарию требуется задержка, проблема в том, что циклы while делают ваш сценарий не отвечающим более 15 секунд, вызывая ошибку времени ожидания сценария.Action Script позволяет только 15 секунд для выполнения вашего скрипта.

Ваш первый цикл while выглядит проблематично, и мне неясно, как значение [0] изменяется, чтобы завершить цикл.Добавьте разрыв в цикл или убедитесь, что условие изменяется, чтобы цикл мог завершиться, и вы должны решить свою проблему.Вы также можете рассмотреть возможность добавления операторов continue к встроенным циклам while, если предполагается, что они будут выполняться только один раз после того, как они найдут ненасыщенное значение.

Лично, поскольку вы используете ActionScript, я бы предложил использовать объекты и прослушиватели для изменения значений вместо того, чтобы перебирать массивы, проверяя изменения.

Вы также можете добавить ручной таймаут для цикла while, но для этого нужно будет включить логику, чтобы он продолжал с того места, где остановился.

//Set timer to 14 seconds
timeout = getTimer() + 14000;
while(true && timeout > getTimer()){
    trace("No Error");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...