Saturday, January 9, 2010

Eclipse RCP - Prevent UI freezing while running long operation

According to this blog post, the number one mistake which Eclipse developers do is running long operations in UI thread. I certainly agree this is a terrible mistake. Doing this will freeze the UI and lead to bad user experience. As stated in this blog, users need to make sure that long running operations run in a separate non-UI thread. But, in Eclipse, it is not very clear when we are in UI thread and when we are not. I attempt to clarify that in this post and explain few related things in more detail.

1) Any regular code, say in createPartControl of a view or an editor are executed in UI thread. Don't do any long operations in this. Spawn off a separate thread and do them there.

2) Code inside any SWT listener methods are also executed by UI thread. This is also stated in the eclipse-tips blog.

3) Code inside run() method in your Action class is also executed by UI thread.

4) Code inside run() method in your Handler class is also executed by UI thread.

5) If you use Jobs API to run long running operations, your code would typically look like this:
Job job = new Job("Long Job") {
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask("Job started...", 10);
// Run long running task here
monitor.done();
return Status.OK_STATUS;
}
};
job.setUser(true);
job.schedule();

Here the code inside run() method is in not in UI thread and you are in worker thread. Running long tasks is fine here. But, what if you want to update UI while your long running task is running. You should use either asyncExec or syncExec for this purpose. I will explain about them in more detail in my next post. If not, you will have problems while running your application.

6) If you just want to show busy indicator while running long operation, your code would typically look like this:

BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(), new Runnable() {
public void run() {
// Long operation goes here
}
});

Unlike point 5, here the code inside run() method is not executed in worker thread. The code is run by UI thread only. So, make sure not to execute too long running operations here.

No comments: