I had some of my runAsync's in the controller, because that is where I know how to calculate progress for task.updateProgress(). But the view presumably is the thing that should be calling task.cancel() and task.updateMessage(). Right now I'm putting runAsync in the view and passing the FXTask to the controller so it can call updateProgress().