public interface Task
Thread along with a user interface to
display its progress, provide a means for the user to
cancel the Task, and show information
about any Exceptions thrown during its
execution.
Tasks are executed as part of a TaskIterator
which will be passed into a TaskManager's execute method.
Some hints for writing a Task:
Task
should not catch it and set a status message or the progress,
even to provide explanatory messages for the user.
A TaskManager may disregard status message
and progress updates once an exception is thrown.
Any helpful user messages regarding the exception should
be contained solely in the exception.Task throws
a low level exception, it should catch it and throw
an exception with a high level description. For example:
try
{
...
}
catch (IOException exception) // Low level exception
{
// Throw a high level exception that gives a high level explanation
// that makes sense for a non-technical user.
throw new Exception("Oops. Looks like you specified an invalid file.", exception)
}
Any helpful messages for the user should be contained in
an exception.Task encounters an error
that is not in the form of an exception, like an invalid
variable or incorrectly formatted parameter,
the Task should not
set the status message giving an explanation of the
error and then exit. Instead, it should throw an exception.
The wrong way:
public void run(TaskMonitor taskMonitor)
{
if (myParameter == null)
{
taskMonitor.setStatusMessage("Whoa, looks like you didn't specified the parameter.");
return;
}
}
The right way:
public void run(TaskMonitor taskMonitor) throws Exception
{
if (myParameter == null)
throw new Exception("Whoa, looks like you didn't specified the parameter.");
}
This is done because it is possible for the TaskManager to close
the Task's user interface when the Task returns
before the user can read the message. Throwing an exception ensures
the user will see the message.Task, when specifying its status message,
should describe what it will do, not what it has done.
Specifically, if the Task has several constituent parts,
it should set its status message at the beginning of a part, not at the
end. For example, assume a Task has two parts, A and B:
public void run(TaskMonitor taskMonitor)
{
taskMonitor.setStatusMessage("Starting part A...");
... // do part A
taskMonitor.setStatusMessage("Part A is done.");
taskMonitor.setStatusMessage("Starting part B...");
... // do part B
taskMonitor.setStatusMessage("Part B is done.");
}
Setting the status message after part A is unnecessary
because the status message is immediately changed when
part B starts. Setting the status message after part B
is unnecessary because the Task ends immediately
after part B finishes. Therefore, Tasks should
set the status message at the beginning of a part.
Task's
should not be specified in the status message. For example:
public void run(TaskMonitor taskMonitor)
{
int result = ... // some complicated computation
taskMonitor.setStatusMessage("The result of the computation is " + result);
// Give the user a chance to read the message:
try
{
Thread.wait(1000);
}
catch (InterruptedException exception) { }
}
This is because the purpose of the status message is to inform the
user what the Task is currently doing, not what it
has done. If the Task wishes to provide any information
regarding what it has done, it must do so through alternate means.
Task should not set the status message or progress
immediately before the Task finishes. This is because the
TaskManager may close the Task's user interface
before the user has a chance to read it. For example:
public void run(TaskMonitor taskMonitor) throws Exception
{
... // Some complicated calculation
// This is unnecessary:
taskMonitor.setStatusMessage("We're all done.");
taskMonitor.setProgress(1.0);
}
Task
should set its progress by using the setProgress
method of TaskMonitor to a value less than 0.
Module: work-api
To use this in your app, include the following dependency in your POM:
<dependency>
<groupId>org.cytoscape</groupId>
<artifactId>work-api</artifactId>
</dependency>| Modifier and Type | Method and Description |
|---|---|
void |
cancel()
This method is called by the
TaskManager when the user chooses to cancel the
Task. |
void |
run(TaskMonitor taskMonitor)
This method is called when the
Task begins execution. |
void run(TaskMonitor taskMonitor) throws Exception
Task begins execution.
This method should not be called by the programmer, as it will be called by the TaskManager.taskMonitor - The TaskMonitor provided by TaskManager.
to allow the Task to modify its user interface.Exception - The Task is at liberty to
throw an exception in run. The exception is
caught by TaskManager and is displayed in the interface.
If a Task does not throw an exception,
the Task implementation does not
need to specify the throws Exception clause
for the run method. Moreover, exceptions
should be the way the Task communicates
the occurrence of a fatal error, like a low-level exception or an invalid parameter,
to the TaskManager.void cancel()
TaskManager when the user chooses to cancel the
Task.
This method should not be called by the programmer, as it might be called by the TaskManager.
This method should inform the Task that it must
terminate execution cleanly and do any necessary cleanup
work required.
WARNING: this method is called by a different
thread than the thread executing run.
The programmer must be aware of
concurrency issues!
Copyright 2011 Cytoscape Consortium. All rights reserved.