0

Problem / Question about EventQueues

asked 2012-09-04 19:13:38 +0800

rappr gravatar image rappr
48

updated 2012-09-04 19:22:54 +0800

Hi,

I modified the example from WIKI Long Operations/Use Event Queues a bit for my issue but it does not work as expected.

<window title="test of long operation" border="normal">
    <html><![CDATA[
    <ul>
    <li>Click the button it will start a long operation.</li>
    <li>With this implementation, you can press the button again even if
    the long operation is still being processed</li>
    </ul>
    ]]></html>
    <zscript>
    void print(String msg) {
        new Label(msg).setParent(inf);
    }
    </zscript>
    <button label="async long op">
        <attribute name="onClick"><![CDATA[
		   if (EventQueues.exists("longop")) {
		     print("It is busy. Please wait");
		     return; //busy
		   }
		 
		   EventQueue eq = EventQueues.lookup("longop"); //create a queue
		   String result;
		 
		   //subscribe async listener to handle long operation
		   eq.subscribe(new EventListener() {
		     public void onEvent(Event evt) {
		       if ("doLongOp".equals(evt.getName())) {
		         eq.publish(new Event("reloadView")); //notify
		         org.zkoss.lang.Threads.sleep(5000); //simulate a long operation
		         result = "success"; //store the result
		         eq.publish(new Event("endLongOp")); //notify it is done
		       }
		     }
		   }, true); //asynchronous
		 
		   //subscribe a normal listener to show the resul to the browser
		   eq.subscribe(new EventListener() {
		     public void onEvent(Event evt) {
		       if ("endLongOp".equals(evt.getName())) {
		         print(result); //show the result to the browser
		         EventQueues.remove("longop");
		       }
			if ("reloadView".equals(evt.getName())) {
				print("TIMER: " + new Date().getSeconds());
				Thread.sleep(1000);
				eq.publish(new Event("reloadView")); // notify to reload of view
			}
		     }
		   }); //synchronous
		 
		   print("Wait for 5 seconds");
		   eq.publish(new Event("doLongOp")); //kick off the long operation
        ]]></attribute>
    </button>
    <vbox id="inf"></vbox>
</window>

What I want to do is:
While the long operation runs (in my real case I import data from a file into a database table), I want to refresh a listbox that shows a log table from database.

So my idea was to publish another event to the queue that does the refresh every second.

In the code above simulated by the
print("TIMER: " + new Date().getSeconds());

After one second I publish the event again.

My expectation was to see the word TIMER every second.
But it only shows up once at the end of the long operation.

What am I doing wrong?

Thanks for any help!

delete flag offensive retag edit

4 Replies

Sort by ยป oldest newest

answered 2012-09-07 07:49:29 +0800

rappr gravatar image rappr
48

Can anyone help me on that?

The publishing of the events does not work as a I would expect.
What do I do wrong?

link publish delete flag offensive edit

answered 2012-09-07 19:35:33 +0800

jj gravatar image jj
638 3

You should either use a working thread, or a Timer. The problem is that there is only one execution thread in ZK (by default configuration), thus when thread sleeps, nothing happens. Below is the working code with Timer implementation:

<window title="test of long operation" border="normal">
    <html><![CDATA[
    <ul>
    <li>Click the button it will start a long operation.</li>
    <li>With this implementation, you can press the button again even if
    the long operation is still being processed</li>
    </ul>
    ]]></html>
    <zscript>
    void print(String msg) {
        new Label(msg).setParent(inf);
    }
    </zscript>
    <button label="async long op">
        <attribute name="onClick"><![CDATA[
		   if (EventQueues.exists("longop")) {
		     print("It is busy. Please wait");
		     return; //busy
		   }
		 
		   EventQueue eq = EventQueues.lookup("longop"); //create a queue
		   String result;
		 	timer.start();
		   //subscribe async listener to handle long operation
		   eq.subscribe(new org.zkoss.zk.ui.event.EventListener() {
		     public void onEvent(Event evt) {
		       if ("doLongOp".equals(evt.getName())) {
		         org.zkoss.lang.Threads.sleep(5000); //simulate a long operation
		         result = "success"; //store the result
		         eq.publish(new Event("endLongOp")); //notify it is done
		       }
		     }
		   }, true); //asynchronous
		 
		   //subscribe a normal listener to show the resul to the browser
		   eq.subscribe(new org.zkoss.zk.ui.event.EventListener() {
		     public void onEvent(Event evt) {
		       if ("endLongOp".equals(evt.getName())) {
			     timer.stop();
		         print(result); //show the result to the browser
		         EventQueues.remove("longop");

		       }
 
		     }
		   }); //synchronous
		 
		   print("Wait for 5 seconds");
		   eq.publish(new Event("doLongOp")); //kick off the long operation
        ]]></attribute>
    </button>
    <vbox id="inf"></vbox>
    <timer id="timer" running="false" delay="1000" repeats="true">    
        <attribute name="onTimer">        
             print("timer called.");    
        </attribute>        
    </timer> 
</window>


link publish delete flag offensive edit

answered 2012-09-10 14:33:19 +0800

rappr gravatar image rappr
48

Thank you jj. That works!

So a timer has its own thread?

Regards, Ralf

link publish delete flag offensive edit

answered 2012-09-10 17:57:37 +0800

jj gravatar image jj
638 3

Yes, otherwise it would be useless.

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2012-09-04 19:13:38 +0800

Seen: 183 times

Last updated: Sep 10 '12

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More