Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-dev] IProgressMonitor - cancelling operations

Hey everybody,

I'd like to stimulate some discussion as to the best approach to deal with a user canceling a long-running operation in CDT 2.0. In particular I was recently stung by an uncaught OperationCanceledException:

  https://bugs.eclipse.org/bugs/show_bug.cgi?id=51250

As a policy for CDT 2.0 and beyond, I propose that UI code should throw InterruptedException rather than OperationCanceledException in response to a user canceling a progress dialog.

To quote from _Contributing to Eclipse_ (Gamma & Beck, p.188):

.   To find out whether a user has requested a cancellation, the
. operation should call [IProgressMonitor] isCanceled() frequently.  If
. the user requests a cancellation, the operation should be terminated
. by throwing an exception.  The exception can be either an
. InterruptedException or an OperationCanceledException.  We prefer
. InterruptedException because wherever possible you want to reuse
. existing types rather than introduce your own.
. (OperationCanceledException is still supported for backwards
. compatibility).  This is a snippet you will find in many Eclipse
. operations:
.
.   if (monitor.isCanceled())
.     throw new InterruptedException();

Operations should be encapsulated inside the invocation method, as in this example build() operation (Gamma & Beck, p.189):

. protected boolean build() {
.   ProgressMonitorDialog dialog= new ProgressMonitorDialog(
.     getShell());
.  try {
.     dialog.run(true, true, new IRunnableWithProgress() {
.       public void run(IProgressMonitor monitor)
.         throws InvocationTargetException {
.           // invoke build
.       }
.     });
.   } catch (InterruptedException e) {
.     return false;
.   } catch (InvocationTargetException e) {
.     Throwable target= e.getTargetException();
.     //TODO inform about target exception
.     return false;
.   }
.   return true;
. }

My main beef with the OperationCanceledException is that it is a RuntimeException and so does not have to be declared with a throws clause and can thus slip through without being caught. As a policy, RuntimeExceptions should be used sparingly, to indicate programming errors (ArrayOutofBounds, etc.) and not to indicate a normal and perfectly valid state of affairs (user clicked the cancel button).

Thoughts?

-Chris


Back to the top