Actionscript- sortCompare函数在排序时冻结应用程序

时间:2014-03-13 05:57:51

标签: actionscript-3 sorting

我正在开发一个具有此AdvancedDataGrid组件的应用程序。其中一列有字符串格式的日期(mm / dd / yyyy) - 所以要根据日期排序,我写了一个函数来调用该列的sortCompare属性:

private function sortDueDate(item1: Object, item2: Object): int {

    this.showPleaseWaitMessage();

    // collect the date values as string and convert into Date objects: 
    var date1: Date = new Date(Date.parse(item1.allocationDate));
    var date2: Date = new Date(Date.parse(item2.allocationDate));

    // compare the 2 date objects:
    return ObjectUtil.dateCompare(date1, date2);
}

此功能适用于5000行数据。很明显,预计会减慢甚至冻结应用程序5-10秒。但是这种sortCompare函数需要大约40-45秒来对数据进行排序。这肯定会让最终用户感到困惑。

所以我写了另一个从上面的sortDueDate()调用的函数来显示一条消息 - “请等待数据被排序。”

private function showPleaseWaitMessage(): void {

    // show message only if this is the 1st iteration:
    if(sortIteration == 1) {  // sortIteration is a private uint only for counting iteration and showing the message at 1st iteration

        formattedAlert = Alert.show("Please wait while the data is being sorted.", "Information", Alert.OK, this, pleaseWaitMessageHandler);
        formattedAlert.styleName = "Alert";

        // set busy cursor:
        CursorManager.setBusyCursor();

        sortIteration++;
    }
    else {

        // do nothing
    }
}

private function pleaseWaitMessageHandler(eventObj: CloseEvent): void {

    // stop busy cursor:
    CursorManager.removeBusyCursor();

    // reset the iteration no. after sorting is complete
    sortIteration = 1;
}

在我尝试运行应用程序之前,所有这些都很好看。但是显示带有忙碌光标的消息的所有努力都是徒劳的,因为所有这些仅在应用程序冻结40-45秒后才会显示。并且在显示消息时,排序在后台完成。 我不能使用分页,因为我们的客户反对这一点,令人惊讶但真实:-)

任何人都可以建议解决这个问题,以便在排序开始之前向用户显示消息......处理这种情况的任何输入都将非常感激!

提前致谢!

2 个答案:

答案 0 :(得分:2)

UI锁定的原因是Flash使用单线程事件循环。每个循环包括几个阶段,其中调度系统事件,调用事件处理程序,最后执行渲染。如果您的代码没有及时向Flash发布控制权,那么整个应用程序就会被冻结。

这是一篇很好的文章,说明了这个概念:Elastic Racetrack for Flash 9 and AVM2

有一些解决方案。最简单的方法是在显示等待消息时允许应用程序锁定(如果应用程序冻结45秒就可以了)。为此,我们需要允许Flash播放器在执行排序之前进行渲染。为此,您可以创建一个ENTER_FRAME事件处理程序,以便在下一帧开始时调用逻辑(在代码将等待消息添加到DisplayList之后)。例如:

stage.addEventListener(Event.ENTER_FRAME, myFunction);
function myFunction(event:Event) {
   // invoke sort logic here
}

另一个解决方案(使用这个概念)是将分类分解成可以分布在几个帧上的较小块的工作,从而允许事件循环循环。

但是,理想的解决方案是利用Flash Player 12的新Worker功能。这允许您在单独的执行线程中执行处理。这可以通过从主应用程序代码调用worker(为其提供所需的数据)并添加一个事件监听器来响应一旦作业完成 - 从而永远不会锁定主事件循环。有关工人的更多信息,请阅读:Worker - AS3

答案 1 :(得分:0)

我终于能够在使用TEXT格式的Date值对列进行排序时解决应用程序冻结的问题。网格有超过5000条记录,此解决方案自动将冻结时间减少到不到5秒(应用程序冻结时间超过45秒)。这就是我的所作所为:

我为AdvancedDataGrid的HEADER_RELEASE事件注册了一个事件监听器:

dgMyGridHere.addEventListener(AdvancedDataGridEvent.HEADER_RELEASE, startSorting);

然后在侦听器方法中,我只检查了no.of记录是否超过1000(大约1000条记录的排序是在闪存中完成的,所以不需要向用户显示消息)。

    /**
     * FUNCTION TO HANDLE THE COLUMN-SORT EVENT.
     **/
    private function startSorting(event: AdvancedDataGridEvent): void {

        // show message to user with busy cursor only if row-count is > 1000 
        if(orgData.length > 1000) {

            this.showPleaseWaitMessage();

            // set busy cursor:
            CursorManager.setBusyCursor();

            // set timer to 5 secs, so that busy cursor is removed after 5 seconds:
            timer = new Timer(5000, 1);
            timer.addEventListener(TimerEvent.TIMER, removeBusyCursor);
            timer.start();
        }
        else {

            // no need to show message
        }

        var sortEvent:AdvancedDataGridEvent = new AdvancedDataGridEvent(AdvancedDataGridEvent.SORT);
        dgAnnualAdvisoryMeeting.dispatchEvent(sortEvent);
    }



    /**
     * FUNCTION TO SHOW A "PLEASE WAIT" MESSAGE.
     **/
    private function showPleaseWaitMessage(): void {

        formattedAlert = Alert.show("Please wait while the data is being sorted.", "Information");
        formattedAlert.styleName = "Alert";
    }

我还将计时器设置为5秒以移除忙碌光标(只是为了让用户知道排序已完成 - 虽然时间不到5秒),这里是计时器监听器事件处理程序:

    /**
     * FUNCTION TO HANDLE THE 5 SECONDS TIMER EVENT AND STOP THE BUSY CURSOR.
     **/
    private function removeBusyCursor(timerEvent: TimerEvent): void {

        // stop busy cursor:
        CursorManager.removeBusyCursor();
    }

那就是它!我希望这有助于任何面临类似问题的人。 感谢Peter让我深入了解了#34; The Frame"处理,但我以另一种方式解决了问题:-) 还有来自" Christofer Dutz"在他的帖子中:

https://dev.c-ware.de/confluence/display/PUBLIC/Programatically+sort+AdvancedDataGrid+columns