[
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