0

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

我已经研究过,我知道如何更新一个简单的进度条,但是这些示例往往过于简单化,因为使用 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 行的输入对其进行了测试,它似乎可以生成与同时处理输入的另一种方法相同的结果。但是,这是一种有效的方法还是有更好的方法?

提前致谢。

4

5 回答 5

0

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

于 2013-11-11T07:50:37.607 回答
0

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

伪线程

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

于 2013-11-11T21:32:51.827 回答
0


您的解决方案很好,我大部分时间都在使用它。
但是现在 AS3 支持多线程(目前仅适用于桌面和 Web)。
看看:Worker 文档Worker 示例
希望有帮助:)

于 2013-11-11T06:02:38.533 回答
0

请问这个定时器是否是工作定时器???因为如果是,那么从长远来看,您的应用程序会遇到很多麻烦!- 重新加载并让计时器停止、关闭等。EventListener 将不完整,肯定会出现问题!

我想建议先把它做好,然后再进一步,因为我从经验中知道,在我自己的一些 AIR 应用程序中,我需要让数百个应用程序在模块以及我的一些 Web 应用程序中一个接一个地运行。没那么激烈还没安静几下!我敢肯定,更令人窒息的处决将是回报!问候阿克特尔

于 2013-11-11T06:21:25.370 回答
0

如果不使用 Workers(您似乎还不熟悉),AS3 将表现为单线程。您的计时器不会重叠。如果您的一个块需要超过 1 秒才能完成,则将尽可能处理下一个计时器事件。如果花费的时间超过您的时间段(假设您的处理代码被阻塞),它将不会排队进一步的事件。

先前的答案显示了对此的“正确”解决方案,但这可能会让您更快地到达需要的地方。

于 2013-11-11T22:37:31.663 回答