Re: Clarification on javafx.concurrent.Task cancellation behavior

2014-05-12 Thread Martin Sladecek

Hi Weiqi,
this is definitely a bug, I filed 
https://javafx-jira.kenai.com/browse/RT-37067 to track this.


Thanks,
-Martin

On 11.5.2014 20:22, weiqi...@gmail.com wrote:

Hi,


Looking at the javafx.concurrent.Task code, I see the following in the nested class 
TaskCallableV’s call() method:


 try {
 final V result = task.call();
 if (!task.isCancelled()) {
 // If it was not cancelled, then we take the return
 // value and set it as the result.
 task.runLater(new Runnable() {
 @Override public void run() {
 // The result must be set first, so that when the
 // SUCCEEDED flag is set, the value will be 
available
 // The alternative is not the case, because you
 // can assume if the result is set, it has
 // succeeded.
 task.updateValue(result);
 task.setState(State.SUCCEEDED);
 }
 });
 return result;
 } else {
 // There may have been some intermediate result in the
 // task set from the background thread, so I want to be
 // sure to return the most recent intermediate value
 return task.getValue();
 }
 } catch (final Throwable th) {
 ….

 }


When this code is executed off the JavaFX Application Thread, which I take to 
be the case almost all the time, the “task.getValue()” call will always throw 
an exception as the getValue() method does a checkThread() first.  Is this 
intentional?


The practical implication is that a cancelled task, in addition to its state 
being CANCELLED, also has an IllegalStateException with a message of “Task must 
only be used from the FX Application Thread” recorded as an exception of the 
task if the task chooses to exit the call() method normally when the task is 
cancelled.  And of course, if the task chooses to exit the call() method 
abruptly by throwing its own RuntimeException, that runtime exception will be 
recorded as the exception of the task instead of the ISE.



--

Weiqi Gao




Clarification on javafx.concurrent.Task cancellation behavior

2014-05-11 Thread weiqigao
Hi,


Looking at the javafx.concurrent.Task code, I see the following in the nested 
class TaskCallableV’s call() method:


try {
final V result = task.call();
if (!task.isCancelled()) {
// If it was not cancelled, then we take the return
// value and set it as the result.
task.runLater(new Runnable() {
@Override public void run() {
// The result must be set first, so that when the
// SUCCEEDED flag is set, the value will be 
available
// The alternative is not the case, because you
// can assume if the result is set, it has
// succeeded.
task.updateValue(result);
task.setState(State.SUCCEEDED);
}
});
return result;
} else {
// There may have been some intermediate result in the
// task set from the background thread, so I want to be
// sure to return the most recent intermediate value
return task.getValue();
}
} catch (final Throwable th) {
….

}


When this code is executed off the JavaFX Application Thread, which I take to 
be the case almost all the time, the “task.getValue()” call will always throw 
an exception as the getValue() method does a checkThread() first.  Is this 
intentional?


The practical implication is that a cancelled task, in addition to its state 
being CANCELLED, also has an IllegalStateException with a message of “Task must 
only be used from the FX Application Thread” recorded as an exception of the 
task if the task chooses to exit the call() method normally when the task is 
cancelled.  And of course, if the task chooses to exit the call() method 
abruptly by throwing its own RuntimeException, that runtime exception will be 
recorded as the exception of the task instead of the ISE.



--

Weiqi Gao