我发现我的Flex应用程序的UI在很长的处理循环(几十秒)内变得没有响应。例如,在处理非常大的XML文件并对每个元素执行某些操作时......
是否有“ProcessMessages”的等价物?也就是说,一个调用会告诉Flex继续响应UI事件,即使在一些长循环的中间,这样UI也不会没有响应?
我知道Flex是单线程设计。这就是为什么我正在寻找像ProcessMessages()这样的函数 - 一个允许单线程可重入应用程序(如在VB中,或基于单线程消息循环的C ++应用程序)的函数在长时间内保持响应操作。
答案摘要
HandleEvents()
或ProcessMessages()
。enterFrame
事件,只要Flex应用程序下面的Flash“影片”图层刷新其帧(类似于20fps),就会调用该事件。UIComponent.callLater()
安排工作“稍后”完成。 (作为文档say:Queues a function to be called later. Before each update of the screen, Flash Player or AIR calls the set of functions that are scheduled for the update.
如果有进一步的建议,或者我遗漏了任何内容,请随时编辑此(现在)维基片。
答案 0 :(得分:6)
问题是Flash是单线程的,即在代码的一部分运行之前,不能进行其他处理。你会以某种方式将处理分解成更小的块,并在enterFrame
事件上执行这些块。
编辑:我担心低估这个(或西蒙的)答案并不会改变这在AS3中无法实现的事实。阅读this article,了解有关该问题的更多信息。该文章还包括一个名为PseudoThread的简单“库”,它有助于执行长背景计算。不过,你仍然需要将问题分解成更小的部分。
答案 1 :(得分:4)
我可以肯定地告诉你,从Flex 3开始,没有类似于你所描述的ProcessMessages
功能的内置结构。
解决此问题的最常见方法是将正在处理的任何工作拆分为“工作”任务队列和“工作管理器”以控制队列。当每个“worker”完成其处理时,worker队列管理器会弹出队列中的下一个worker并在callLater()
调用中执行它。这将产生类似于“屈服于主线程”的效果,并允许您的UI接收事件并做出响应,同时仍然允许在将控制权返回给工作者时继续处理。
一旦你有了这个工作,你可以做一些测试和分析,以确定你的应用程序是否可以在调用callLater()
之前执行多个工作程序的运行,并将此逻辑封装在工作队列中经理。例如,在我们的这种模式的实现中(队列中有几百个工作者),我们能够通过执行4个工作人员在“屈服于主线程”{{{{ 1}},但这完全取决于你的工人正在做的工作的范围和性质。
答案 2 :(得分:2)
ActionScript的流程模型是单线程的,所以答案是否定的。最好的办法是,如果可以的话,要么推迟服务器上的异步任务,要么在长循环运行时弹出一个等待光标,或者将你的进程分解成一些不那么具有侵入性的小块,或者执行当用户不太可能感受到效果时(例如,应用启动),长时间运行的任务。
答案 3 :(得分:2)
Actionscript是单线程设计,没有任何downvoting答案会改变这一点。
为了兼容性,您最好的办法是尝试将处理拆分为更小的块,然后迭代进行处理。
如果您绝对需要线程,则可以使用Pixel Bender过滤器在Flash Player 10中完成排序。这些将在一个单独的线程上运行,一旦完成就可以给你一个回调 我相信它们非常适合“硬核”处理任务,因此它们可能很适合您的目的。 但是,它们会对您的代码提出另外一组要求,因此您可能更好地进行计算的小“桶”。
答案 4 :(得分:1)
Flash Player中没有等效功能。按照设计,Flash Player在渲染到屏幕之间交替,然后为每个帧运行所有代码。在显示对象上使用Event.ENTER_FRAME
事件,或在其他地方使用Timer
个对象,是打破很长时间计算的最佳选择。
值得注意的是,ActionScript中的某些事件具有updateAfterEvent()
函数,其描述如下:
如果已修改显示列表,则指示Flash Player或AIR运行时在此事件处理完成后呈现。
特别是,TimerEvent
,MouseEvent
和KeyboardEvent
支持updateAfterEvent()
。可能还有其他人,但这些是我通过快速搜索找到的。