Long-running processes
This site shows how to handle the long-running processes in the UI.
Basically, it should be avoided to execute long-running processes in the UI. If it is still necessary, you have to ensure that these processes do not run on the UI-thread. This article illustrates the possibilities one has to deal with it.
Rule number one: Do not block the UI thread!
If you write code which will be used by any UI components. You must always take care that the code does not include calls that can take a long time
protected
void
someMethodInUI()
{
final
String label = someBusinessObject.invokeVeryLongOperation();
someUiObject.setText( label );
}
The problem in the line 3 is: you don't know how much time takes this call. And so long as the call lasts, the UI thread is waiting. In other words: the UI hangs.
Best Practice
The best practice to avoid this issue is to run the long-running processes within an eclipse job:
RunnableWithProgress runnable =
new
RunnableWithProgressBaseImpl()
{
@Override
protected
void
doRunWithCoreException( IProgressMonitor progressMonitor )
throws
CoreException, InterruptedException
{
invokeVeryLongOperation();
}
};
IProgressService progressService = PlatformUI.getWorkbench()
.getProgressService();
Job job =
new
RunnableWithProgressJob( jobName, runnable );
job.schedule();
progressService.showInDialog( shell, job );
Important is to schedule the job before showing it in a dialog via the progress service. In this case the progress service waits for a short duration before opening the progress dialog. Otherwise the dialog appears always, also if the operation lasts only few miliseconds.
The advantage of using jobs is the possibility to add a JobListener to the job to be notified when the job is done:
job.addJobChangeListener(
new
JobChangeAdapter()
{
@Override
public
void
done( IJobChangeEvent event )
{
// IMPORTANT: access the UI stuff only within the UI thread!!!
Display.getDefault()
.asyncExec(
new
Runnable()
{
@Override
public
void
run()
{
updateUI();
}
} );
}
} );
If you don't want to show the progress dialog, you can also use an other function of the progress service: showing a busy cursor while an operation is running:
RunnableWithProgress runnable =
new
RunnableWithProgressBaseImpl()
{
@Override
protected
void
doRunWithCoreException( IProgressMonitor progressMonitor )
throws
CoreException, InterruptedException
{
invokeVeryLongOperation();
}
};
IProgressService progressService = PlatformUI.getWorkbench()
.getProgressService();
progressService.busyCursorWhile(
new
RunnableWithProgressWrapper( runnable ) );
Disadvantages of this method:
the user is forced to wait until the operation is finished
no listener registration is possible (e.g. to be notified when the operation is done)