所以我有以下脚本来获取数组的所有组合: '''
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毫秒,然后继续。
任何帮助表示赞赏。
答案 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)