Asynchronous Tasks"

From Documentation
m ((via JWB))
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
{{ZKDevelopersReferencePageHeader}}
 
{{ZKDevelopersReferencePageHeader}}
  
If the task of updating UI can be represented as a method, the push can be done easily. All you need to do is
+
If you run an application logic in a task thread (not in a servlet thread), and you don't want to update UI in the same thread. All you need to do is:
#Implement the UI updates in an event listener (implementing <javadoc type="interface">org.zkoss.zk.ui.event.EventListener</javadoc> or <javadoc type="interface">org.zkoss.zk.ui.event.SerializableEventListener</javadoc>).
 
#Then, schedule it for executed asynchronously by the use of <javadoc method="schedule(org.zkoss.zk.ui.Desktop, org.zkoss.zk.ui.event.EventListener, org.zkoss.zk.ui.event.Event)">org.zkoss.zk.ui.Executions</javadoc>.
 
  
Here is the pseudo code:
+
# enable server push
<source lang="java">
+
# Implement the UI updates in an event listener (implement <javadoc type="interface">org.zkoss.zk.ui.event.EventListener</javadoc> or <javadoc type="interface">org.zkoss.zk.ui.event.SerializableEventListener</javadoc>).
// in a separate thread, other than a servlet thread
+
# Execute the listener asynchronously by <javadoc method="schedule(org.zkoss.zk.ui.Desktop, org.zkoss.zk.ui.event.EventListener, org.zkoss.zk.ui.event.Event)">org.zkoss.zk.ui.Executions</javadoc>.
// run a long task
 
// then push the result on UI
 
Executions.schedule(desktop,
 
    new EventListener() {
 
        public void onEvent(Event event) {
 
            updateUI(); //whatever you like
 
        }
 
    }, event);
 
</source>
 
  
You could manipulate UI whatever you want in <javadoc type="interface" method="onEvent(org.zkoss.zk.ui.Event)">org.zkoss.zk.ui.event.EventListener</javadoc>. It is no different from any other event listener.
+
Here is the code snippet:
 +
<syntaxhighlight lang="java" line>
 +
    @Listen("onClick = #start")
 +
    public void start() throws ExecutionException, InterruptedException {
 +
        // run in a separate thread
 +
        CompletableFuture.runAsync(() -> {
 +
            Threads.sleep(3000); //simulate a long task
 +
            Executions.schedule(desktop,
 +
                new EventListener<Event>() {
 +
                    public void onEvent(Event event) {
 +
                        //update UI
 +
                        status.setValue("done at " + LocalDateTime.now());
 +
                    }
 +
                }, new Event("myEvent"));
 +
        });
 +
    }
 +
</syntaxhighlight>
 +
* Line 10: You can manipulate ZK UI components in <javadoc type="interface" method="onEvent(org.zkoss.zk.ui.Event)">org.zkoss.zk.ui.event.EventListener</javadoc>. It is no different from any other event listener.
  
Notice that <javadoc method="schedule(org.zkoss.zk.ui.Desktop, org.zkoss.zk.ui.event.EventListener, org.zkoss.zk.ui.event.Event)">org.zkoss.zk.ui.Executions</javadoc> can be called anywhere, including another event listener or a working thread. In other words, you don't have to fork a working thread to use this feature.
+
Notice that <javadoc method="schedule(org.zkoss.zk.ui.Desktop, org.zkoss.zk.ui.event.EventListener, org.zkoss.zk.ui.event.Event)">org.zkoss.zk.ui.Executions</javadoc> can be called anywhere, including another event listener or a task thread. In other words, you don't have to fork a new thread to use this feature.
 +
 
 +
Notice that, since there is at most one thread to access the UI of a given desktop, the event listener must NOT be time-consuming. Otherwise, it will block other event listeners from execution. Thus, if you have a long operation to do, you could use [[ZK_Developer's_Reference/Event_Handling/Event_Queues#Asynchronous_Event_Listener|event queue's asynchronous event listener]], or implement it as [[ZK Developer's Reference/Server Push/Synchronous Tasks|a synchronous task]] and handle lengthy operation outside of the activation block.
  
Notice that, since there is at most one thread to access the UI of a given desktop, the event listener's performance must be good. Otherwise, it will block other event listeners from execution. Thus, if you have a long operation to do, you could use [[ZK_Developer's_Reference/Event_Handling/Event_Queues#Asynchronous_Event_Listener|event queue's asynchronous event listener]], or implement it as [[ZK Developer's Reference/Server Push/Synchronous Tasks|a synchronous task]] and handle lengthy operation outside of the activation block.
 
  
 
=Version History=
 
=Version History=
{{LastUpdated}}
+
 
{| border='1px' | width="100%"
+
{| class='wikitable' | width="100%"
 
! Version !! Date !! Content
 
! Version !! Date !! Content
 
|-
 
|-

Latest revision as of 07:37, 8 July 2022


Asynchronous Tasks


If you run an application logic in a task thread (not in a servlet thread), and you don't want to update UI in the same thread. All you need to do is:

  1. enable server push
  2. Implement the UI updates in an event listener (implement EventListener or SerializableEventListener).
  3. Execute the listener asynchronously by Executions.schedule(Desktop, EventListener, Event).

Here is the code snippet:

 1     @Listen("onClick = #start")
 2     public void start() throws ExecutionException, InterruptedException {
 3         // run in a separate thread
 4         CompletableFuture.runAsync(() -> {
 5             Threads.sleep(3000); //simulate a long task
 6             Executions.schedule(desktop,
 7                 new EventListener<Event>() {
 8                     public void onEvent(Event event) {
 9                         //update UI
10                         status.setValue("done at " + LocalDateTime.now());
11                     }
12                 }, new Event("myEvent"));
13         });
14     }

Notice that Executions.schedule(Desktop, EventListener, Event) can be called anywhere, including another event listener or a task thread. In other words, you don't have to fork a new thread to use this feature.

Notice that, since there is at most one thread to access the UI of a given desktop, the event listener must NOT be time-consuming. Otherwise, it will block other event listeners from execution. Thus, if you have a long operation to do, you could use event queue's asynchronous event listener, or implement it as a synchronous task and handle lengthy operation outside of the activation block.


Version History

Version Date Content
5.0.6 November 2010 This feature was introduced. With 5.0.5 or prior, you have to use Event Queues or Synchronous Tasks.



Last Update : 2022/07/08

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.