Time for action – running operations in the background

If the command takes a long time to execute, the user interface will be blocked. This happens because there is only one user interface thread, and because the command is launched from the UI, it will run in the UI thread. Instead, long-running operations should run in a background thread, and then once finished, be able to display the results. Clearly creating a new Thread (like the clock updates initially) or other techniques such as a Timer would work. However, the Eclipse system has a mechanism to provide a Job to do the work instead, or UIJob to run in the context of the UI thread.

  1. Open the HelloHandler and go to the execute method. Replace its contents with the following:
    public void execute() {
      Job job = new Job("About to say hello") {
        protected IStatus run(IProgressMonitor monitor) {
          try {
            Thread.sleep(5000);
          } catch (InterruptedException e) {
          }
          MessageDialog.openInformation(null, "Hello", "World");
          return Status.OK_STATUS;
        }
      };
      job.schedule();
      return;
    }
  2. Run the Eclipse instance, and click on the Help | Hello menu item (in order to enable the menu item again, modify the activeContexts in the plugin.xml to allow the command to be shown in the org.eclipse.ui.contexts.dialogAndWindow context). Open the Progress view, and a Job will be listed with About to say hello running. Unfortunately, an error dialog will then be shown:
    Time for action – running operations in the background
  3. This occurs because the Job runs on a non-UI background thread, so when the MessageDialog is shown, an exception occurs. To fix this, instead of showing the MessageDialog directly, a second Job or Runnable can be created to run specifically on the UI thread. Replace the call to the MessageDialog with:
    public void execute(final UISynchronize display) {
    ...
    // MessageDialog.openInformation(null, "Hello", "World");
    display.asyncExec(() -> {
        MessageDialog.openInformation(null, "Hello", "World");
    });

    This example uses the asyncExec method to run a Runnable on the UI thread (similar to SwingUtilities.invokeLater method in Swing).

  4. Run the target Eclipse instance, select the Hello menu, and after a 5-second pause, the dialog should be shown.

What just happened?

Every modification to the Eclipse UI must run on the UI thread; so if the command takes a significant time to run and is running on the UI thread, it will give the impression that the user interface is blocked. The way to avoid this is to drop out of the UI thread before doing any long-term work. Any updates that need to be done involving the UI should be rescheduled back on the UI thread.

The example used both the Job API (a mechanism for scheduling named processes that can be monitored via the progress view) as well as the UISynchronize method asyncExec to launch the resulting message dialog.

Have a go hero – using a UIJob

Instead of scheduling the UI notification piece as a display.asyncExec, create it as a UIJob. This works in exactly the same way as a Job does, but it is necessary to override the runInUIThread method instead of the run method. This may be useful when there is more UI interaction required, such as asking the user for more information.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.33.41