Thursday, September 8, 2016

Best Practice: Never ever execute long running operations in the Display.asyncExec() also

//The thread which calls this method is suspended until the runnable completes.
Display.getDefault().syncExec(new Runnable()
{
public void run()
{
//Do only UI operation
}
});


//The caller of this method continues to run in parallel
Display.getDefault().asyncExec(new Runnable()
{
public void run()
{
//Do only UI operation
}

});



I've seen most of the people will misuse Display.getDefault().asyncExec() by thinking that it will not impact the application performance. But the important thing to remember here is, SWT is a single threaded model - Yes, it's a single-threaded UI model. Any UI operation which you do, will happen through Display main thread. 


Example:

Display.getDefault().asyncExec(new Runnable()
{
public void run()
{
   //step 1: network connection involvement
                               
   //step 2: UI code to execute - example: opening a browser

}

});



From above, it has non-UI and UI code. If accessing the network takes time, UI thread will be blocked for a long time so that no other thread can able to get an access to execute other UI code.

That means, at any point of time - only one UI thread will be there i.e, Display thread.


To resolve this kind of things, we need to use jobs and invoke only necessary code in the UI thread.


new Job("Browser opening job...")
{
@Override
protected IStatus run(IProgressMonitor monitor)
{
//step 1: network connection involvement
Display.getDefault().asyncExec(new Runnable()
{
public void run()
{
 //step 2: UI code to execute - example: opening a browser                  
         
}
});

return Status.OK_STATUS;
}
}.schedule();



No comments:

Post a Comment