Я однажды реализовал псевдо-многопоточность в AS3 путем разбиения задачи на куски вместо разделения данных на куски.
Мое решение может быть неоптимальным, но оно работало хорошо дляя в контексте выполнения большого поиска в глубину, в то же время позволяя флэш-игре хорошо воспроизводиться.
- Используйте переменную ticks для подсчета "тиков" вычислений, аналогично CPUтактыКаждый раз, когда вы выполняете какую-либо операцию, вы увеличиваете этот счетчик на 1. Увеличивайте его еще больше после выполнения более тяжелой операции.
- В определенных частях вашего кода вставляйте контрольные точки, где вы проверяете, если ticks > threshold , где threshold - это параметр, который вы хотите настроить после того, как эта псевдо-многопоточность работает.
- Если отметка> порог на контрольной точке, вы сохраняететекущее состояние вашей задачи, установите тики на ноль, затем выйдите из функции.
- Метод должен быть повторен позже, поэтому здесь вы используете таймер с параметром interval , который также должен бытьнастроен позже.
- При перезапуске метода используйте сохраненное состояние приостановленной задачи, чтобы определить, где ваша задача должна быть возобновлена.
Для вашей конкретной ситуации я бы предложил разбитьзадачи циклов для , вместо того, чтобы думать о цикле while.Идея состоит в том, чтобы прервать циклы for, запомнить их состояние, а затем продолжить после интервала покоя.
Для упрощения представьте, что у нас есть только самый лучший цикл for.Эскиз нового метода:
WhileLoop: while (dataInput.bytesAvailable > 0 && ticks < threshold)
{
if(!didSubTaskA) {
// do subtask A...
ticks += 2;
didSubTaskA = true;
}
if(ticks > threshold) {
ticks = 0;
restTimer.reset();
restTimer.start(); // This dispatches an event that should trigger this method
break WhileLoop;
}
for (var i:int = next_unused_i;i < readSampleLength;i+=4) {
next_unused_i = i+1;
// do subtask B...
ticks += 1;
if(ticks > threshold) {
ticks = 0;
restTimer.reset();
restTimer.start();
break WhileLoop;
}
}
next_unused_i = 0;
didSubTaskA = false;
}
if(ticks > threshold) {
ticks = 0;
restTimer.reset();
restTimer.start();
}
Переменные Тики , Порог , restTimer , next_unused_i и didSubTaskA важны и не могут быть локальными переменными метода.Они могут быть статическими или переменными класса.Подзадача A - это та часть, где вы «пересчитываете логические переменные», а также используемые там переменные не могут быть локальными переменными, поэтому сделайте их также переменными класса, чтобы их значения могли сохраняться при выходе из системы и возвращении к методу.
Вы можете сделать его более приятным, создав собственный класс Task и сохранив там все состояние прерванного алгоритма.Кроме того, вы можете сделать контрольную точку локальной функцией.
Я не тестировал приведенный выше код, поэтому не могу гарантировать, что он работает, но идея в основном такова.Надеюсь, это поможет