默认情况下,ZK在一个被称为事件处理线程的独立线程中处理事件。因此,开发人员可以在任何时间挂起和恢复执行,而无需阻塞将响应送回服务器的servlet线程(without blocking the servlet thread from sending back the responses to the browser.)。
但是,这消耗了更多的内存,尤其是有许多被挂起的线程的时,且可能会在整合其它系统时引起一些挑战(challenge),这些系统将信息存储在Servlet的本地存储器中(Servlet thread's local storage)。
ZK提供了一个选择,用来禁用事件处理线程。换言之,你可以强制ZK在Servlet线程中处理所有的事件,就像其它的传统框架。当然,若Servlet 线程已被使用,你可以挂起执行。
为禁用事件处理线程,你必须在WEB-INF/zk.xml
文件中指定下面的代码。
<system-config> <disable-event-thread/> </system-config>
这里是使用Servlet线程处理事件的优点和局限。在下面的章节中,我们将会更多的讨论关于使用Servlet线程时的限制和工作区时(workaround)。
使用Servlet线程 |
使用事件处理线程 | |
---|---|---|
整合(Integration) |
很少的整合问题。 很多容器假定HTTP请求在servlet内被处理。 |
你或许必须实现EventThreadInit和/或EventThreadCleanup来解决整合问题。 ZK和社会(community)会不断提供更多的实现来解决整合问题。 |
挂起 恢复 (SuspendResume) |
没有办法挂起事件监听器的执行。 例如,你可以创建一个模态窗口。 |
根本没有限制。 |
你可以不再使用模态窗口。你可以使用highlighted 模式创建相同的视觉效果。但是,在服务器端,它就像overlapped模式一样工作-立即返回而无需等待用户的响应。
win.doHighlighted(); //returns once the mode is changed; not suspended
消息框会立即返回,所以总是返回Messagebox.OK
。因此,对于显示OK按钮以外的按钮,它是没有意义的。例如,下面例子中的if
子
句(clause)就不会为true。
if (Messagebox.show("Delete?", "Prompt", Messagebox.YES|Messagebox.NO, Messagebox.QUESTION) == Messagebox.YES) { this_never_executes(); }
这样,你必须要提供一个事件监听器,如下:
Messagebox.show("Delete?", "Prompt", Messagebox.YES|Messagebox.NO, Messagebox.QUESTION, new EventListener() { public void onEvent(Event evt) { switch (((Integer)evt.getData()).intValue()) { case Messagebox.YES: doYes(); break; //the Yes button is pressed case Messagebox.NO: doNo(); break; //the No button is pressed } } } );
你提供的事件监听器在用户点击其中一个按钮时会被调用。然后,你可以通过测试数据(事件的getData
方法)来确定哪个按钮被按下。数据为一个整数,其值为按钮的标识,例如Messagebox.YES
。
public void onEvent(Event evt) { if ("onYes".equals(evt.getName())) { doYes(); //the Yes button is pressed } else if ("onNo".equals(evt.getName())) { doNo(); //the No button is pressed } }
注:OK按钮的事件名称为onOK
,而不是onOk
。