4

我有一种情况,我正在启动许多对象,当它们准备好处理一些输入数据时,调用一个处理程序。

该处理程序从待处理请求的 ArrayCollection 中获取数据集,将其分配给对象,然后从 ArrayCollection 中删除数据集。

(我无法从 ArrayCollection 中弹出,因为我需要搜索它以找到合适的数据集 - 它并不总是最重要的。)

是否有可能两个对象可以通过以下方式调用我的处理程序:(1)第一个被分配一个数据集,(2)第二个被分配相同的数据集,然后服务于第一个的处理程序实例删除它,我猜(3) 试图从 ArrayCollection 中删除数据集时处理程序的第二个实例出错。

我对 Flash Player 运行时不够熟悉,不知道这种故障情况是否可能发生,或者我是否应该花额外的时间来设置某种锁定以防止它发生。


编辑:到目前为止,答案对 Flex 给出了热烈的评价,但我不确定他们是否回答了这个问题。需要明确的是,我并不是要决定是否使用 Flex。

如果我有一个方法:

  1. 从 ArrayCollection 中的某处获取一条数据
  2. 用这些数据做点什么
  3. 从 ArrayCollection 中删除该数据

是否有可能在第一次调用 #1 之后但在 #3 之前,同一方法的另一个调用可以执行 #1?

le dorfier,您说 Flex/AS “正常工作” - 你能澄清一下它在这种情况下“正常工作”吗?

4

3 回答 3

8

您不需要进行锁定,但您可能想要跟踪对您的状态的修改顺序。正在运行的不同异步调用可能会以与发出异步调用时不同的顺序返回和修改模型状态。

Flex 和 AIR 应用程序具有单线程编程模型。然而,他们的架构依赖于异步 I/O 来与服务器层进行交互。

现在在 Java Swing 应用程序或 .NET Winforms 应用程序中,可能会在后台线程上进行 i/o 交互,并将参数/结果编组到主 GUI 线程或从主 GUI 线程编组。(那些图形 UI 库不允许其他线程更改图形工具包对象/小部件的状态,因此数据交互必须与其他后台处理线程进行编组。)

相比之下,Flex 和 AIR 的 i/o 类库是在这些类异步实现 i/o 操作的地方编写的。例如,要执行 HTTP GET,可以调用 HttpSerivce send() 方法,这不是阻塞调用。相反,只要调用最终完成并返回,就可以提供一个 ActionScript3 闭包来处理结果。

同时,Flex/AIR 应用程序可以允许 GUI 继续与用户完全交互。它甚至可以显示进度指示器和/或取消按钮。

因此事实证明,尽管 Flex/AIR 单线程 GUI 模型比多线程 Java Swing 或 .NET Winform 应用程序更简单、更易于编程,但它能够实现与那些富客户端应用程序。

一个简单的事件驱动的单线程 GUI、异步 i/o(通过服务调用和/或消息传递),再加上用于处理结果或故障的 ActionScript3 闭包,是 Flex/AIR 统治世界的秘诀。(当然,我应该提到对属性、事件和良好的声明式(或命令式)数据绑定的良好支持,作为这个世界征服战略的一部分。)

于 2009-01-10T01:55:10.417 回答
2

正如您所描述的那样,您的问题的答案是否定的。虽然了解事件注册、事件分派、优先级、异步性等都是有价值的,但事实仍然是您正在主线程上的单个函数范围内修改 ArrayCollection,随后将该函数的第二次调用,也在主线程上——所以你在并发方面没有什么可担心的:虽然你可能不知道哪个对象首先到达那里(出于很多原因),但你可以肯定第二个会得到第一个所做的工作的产品。

所以不,你可以走了。摇滚吧!

于 2009-01-10T17:48:53.597 回答
1

在将自己埋在 Flex 和 Actionscript 中几个月之后,我又回到了 .NET。我对我必须选择的所有各种模式感到有点不知所措——或者,我必须从中选择和编排。

相比之下,Flex/AIR 有一组简单但完整的 SDK 调用,用于数据和文件操作,每个调用都有同步和异步变体。它更容易理解和一致使用。

根据我的经验,罗杰是对的。Flex/AS# 可以正常工作。.NET,逐渐减少(来自选项重载,恕我直言)。结果之一是 .NET 更好地适应边缘场景。但如果 Flex/AS3 可以满足您的要求,它可能会很容易做到。想想 80/20 规则(或者可能更好。)

我认为 Roger 已经解决了您的问题,但让我按照我听到的方式说出来。

您的方法是通用 UI 线程上的单线程(以及其他 UI 活动)。但是资源(文件、dbms 端口等)通常会经历一个简单的序列,您通常会像这样设置:

  1. 实例化所需资源类的对象,
  2. 为对象上的返回事件注册一个事件处理程序(比如“fileonOpen”),
  3. 调用对象的异步执行方法(比如“file.open”)。
  4. UI 事件循环继续,
  5. 资源最终完成其方法执行,并触发您注册的事件处理程序,该处理程序现在在 UI 线程上运行,也许您的问题的答案是事件处理程序被赋予了一个参数,该参数是它所属的对象,所以你可以将其从您的收藏中删除。大概您的对象已经足够自我识别,以防止在处理它所属的集合时出现混淆。如果它是一个数据库结果行,它大概会知道它自己的 PK 值。File 对象具有 nativePath、isDirectory、parent(另一个 File 对象)等属性。
于 2009-01-10T02:00:31.437 回答