在没有混合逻辑的情况下在Actionscript / Flash Builder中显示长时间运行进程的进度条

时间:2013-11-11 05:10:29

标签: multithreading actionscript-3 progress-bar flex3

我正在开发一个应用程序来处理(可能很大,达到一两百万行)文本(以制表符分隔的形式)包含项目详细信息的文件,因为处理时间可能很长我想更新进度条所以用户知道应用程序不只是挂起或更好,以提供剩余时间的概念。

我已经研究过,我知道如何更新一个简单的进度条,但是使用Timer调用progressBar.setProgress(counter ++,100)之类的例子往往很简单,还有其他逻辑很简单的例子并写在同一个班级。我也是那种过去主要使用Java和一些JavaScript的语言的新手。

我编写了处理文件的逻辑(输入验证和输出文件的创建)。但是,如果我在主类中调用处理逻辑,则更新将在处理结束时完成(从0到100飞得很快),无论我是否更新变量并尝试调度事件或类似事件;条形图不会反映处理进度。

通过块处理输入是一种有效的方法吗?然后,我不确定一个数据块的处理延迟是否会影响下一个块的处理,依此类推,因为计时器滴答设置为1毫秒,块处理时间将长于。此外,如果输入的顺序不受影响或结果将以某种方式损坏。我读过这种语言不支持多线程,所以这应该是一个问题吗?

我已经编写了之前描述的逻辑,它似乎有效:

// called by mouse click event
function processInput():void { 
    timer = new Timer(1);
    timer.addEventListener(TimerEvent.TIMER, processChunk);
    timer.start();
}

function processChunk(event:TimerEvent):void {

    // code to calculate start and end index for the data chunk, 
    // everytime processChunk is executed these indexes are updated

    var dataChunk:Array = wholeInputArray.splice(index0, index1);

    processorObj.processChunk(dataChunk)

    progressBar.setProgress(index0, wholeInputArray.length); 
    progressBar.label = index0 + " processed items";

    if(no more data to process) { // if wholeInputArray.length == index1
        timer.stop();

        progressBar.setProgress(wholeInputArray.length, wholeInputArray.length); 
        progressBar.label = "Processing done";

        // do post processing here: show results, etc.
    }   
}

进度条的声明如下:

<mx:ProgressBar id="progressBar" x="23" y="357" width="411" direction="right" 
labelPlacement="center" mode="manual" indeterminate="false" />

我使用50000行的输入对其进行了测试,它似乎与另一个处理输入的方法产生相同的结果。但是,这是一种有效的方法还是有更好的方法?

提前致谢。

5 个答案:

答案 0 :(得分:0)


你的解决方案很好,我大部分时间都在使用它。
但AS3现在支持多线程(目前仅适用于桌面和Web)。
请查看:Worker documentationWorker exemple
希望有所帮助:)

答案 1 :(得分:0)

请问这个定时器是否是工作定时器???因为如果是,那么从长远来看,你的应用程序会遇到很多麻烦! - 重新加载&amp;让Timer停止,关闭等等。事件Listener将是不完整的,肯定会给出问题!

我想建议在进一步开发之前先做好准备,因为我从经验中了解到,在我自己的一些AIR应用程序中,我需要有几百个在模块中以及在我的一些模块中一个接一个地运行网络应用。不安静这么激烈但有几个! 我相信更加讽刺的执行将是奖励!关于aktell

答案 2 :(得分:0)

使用Workers。因为将数据拆分成块然后处理它是一种有效但非常麻烦的方法,对于工作人员,您可以简单地生成后台工作程序,在那里进行所有解析并返回结果,所有这些都不会阻止GUI。工作者方法应该花费更少的时间来进行解析,因为不需要停止解析器并等待下一帧。

答案 3 :(得分:0)

工人将是一个理想的解决方案,但设置起来相当复杂。如果你现在还没达到它,这是我在类似情况下使用的PseudoThread解决方案,您可以在5分钟内启动并运行:

Pseudo Threads

它使用EnterFrame事件来平衡工作并让UI完成它的工作,您可以手动更新“线程”代码中的进度条。我认为它很容易适应您的需求,因为您的数据很容易切片。

答案 4 :(得分:0)

不使用Workers(看起来你还不熟悉),AS3会表现出单线程。你的计时器不会重叠。如果你的一个块需要超过1秒来完成,那么下一个计时器事件将被处理。如果超过您的时间段(假设您的处理代码阻塞),它将不会排队其他事件。

之前的答案显示了“正确”的解决方案,但这可能会让您获得更快的速度。