任务挂起
当我通过IntelliJ运行应用程序(最新版本)时,我的最后一项任务是永久挂起。 其实我试图调试,它挂在fetchRegisterCourseList()。 我可以看到它挂起,因为我有一个进度指示器,并且从未获取特定数据。另一方面,当我将我的应用程序打包到jar并正常执行时,它永远不会挂起,一切正常。任务挂起
这是一个IntelliJ或代码相关的错误?
AuthController:
... // previous tasks
Task<List<Course>> parseGradesTask = new Task<List<Course>>() {
@Override
public List<Course> call() {
return studentParser.parseStudentGrades();
}
};
Task<HashMap<String, String>> parseRegTask = new Task<HashMap<String, String>>() {
@Override
public HashMap<String, String> call() {
return studentParser.parseStudentRegistration();
}
};
parseGradesTask.setOnSucceeded(e -> {
serializeService.serializeCourses(parseGradesTask.getValue());
progressIndicator.setProgress(0.6);
});
parseRegTask.setOnSucceeded(e -> {
// it is hanging at this line:
List<Course> regList = serializeService.fetchRegisterCourseList(parseGradesTask.getValue(), parseRegTask.getValue());
serializeService.serializeRegister(regList);
updateMainComponents();
});
ExecutorService es = Executors.newSingleThreadExecutor();
es.submit(parseInfoTask);
es.submit(parseGradesTask);
es.submit(parseStatsTask);
es.submit(parseRegTask);
es.shutdown();
private void updateMainComponents() {
MainController.getInstance().updateAllViewComponents();
if (preferenceService.getPreferences().getPrefSyncEnabled()) {
SyncScheduler.getInstance().stopScheduler();
SyncScheduler.getInstance().startSyncScheduler(preferenceService.getPreferences().getPrefSyncTime());
}
dialogStage.close(); //close this window
}
serializeService:
public List<Course> fetchRegisterCourseList(List<Course> courseList, HashMap<String, String> courseIdList) {
List<Course> courseRegList = new ArrayList<>();
Iterator it = courseIdList.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
courseRegList.addAll(courseList.stream().filter(course ->
course.getCourseId().equals(pair.getKey()) && course.getCourseTitle().equals(pair.getValue()))
.collect(Collectors.toList()));
it.remove(); // avoids a ConcurrentModificationException
}
return courseRegList;
}
的onSuceeded
处理程序被调用在JavaFX应用程序THEAD。这里不应该进行长时间运行的操作。最好只在这里做UI更新。 Task
的结果可用于“发布”操作的结果。该值可以在onSucceeded
处理程序中检索。
在您的代码中,您正在onSucceeded
处理程序中运行这些操作,这会阻止UI线程。
下面的示例演示如何使用Task
正确:
@Override
public void start(Stage primaryStage) {
TextArea textArea = new TextArea();
Button button = new Button("Get Text");
button.setOnAction(evt -> {
button.setDisable(true);
Task<String> task = new Task<String>() {
@Override
protected String call() throws Exception {
// do long-running operations not modifying the UI
// here
StringBuilder sb = new StringBuilder();
final int count = 10;
for (int i = 0; i < count; i++) {
// update message & progress
// the messageProperty/progressProperty will be modified on
// the javafx application thread
updateProgress(i, count);
updateMessage("Loading part " + (i+1));
// simulate long-running operation
Thread.sleep(500);
sb.append('\n').append(i);
}
updateProgress(count, count);
return sb.toString();
}
};
// while loading, display the task message in the TextArea
textArea.textProperty().bind(task.messageProperty());
task.setOnSucceeded(succeededEvent -> {
// only modifications of the UI here, no longrunning tasks
textArea.textProperty().unbind();
// use result of the task
textArea.setText(task.getValue());
button.setDisable(false);
});
// run task on different thread
new Thread(task).start();
});
Scene scene = new Scene(new VBox(textArea, button));
primaryStage.setScene(scene);
primaryStage.show();
}
可以updateProgress和updateMessage()内使用call()?我想从命名这些方法正在改变属性到主要的JavaFX线程。 – pror21
@ pror21我在调用方法中使用了这些方法,不是吗?那些确实可以从这个方法调用,即使它运行在不同的线程上,请参阅https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html#updateProgress-long-long-和https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html#updateMessage-java.lang.String- – fabian
ahh我不知道这些方法是任务类的一部分。有趣!再次感谢 – pror21
IDK什么所有这些语句都在做,但昂贵的任务应该在'Task's的'call'方法来完成。我没有看到你从'onSucceeded'处理器得到任何结果,这看起来更奇怪。从方法名中猜测'updateMainComponents();'应该是'parseRegTask'的'onSucceeded'处理程序中唯一执行的。 – fabian
谢谢fabian。这似乎解决了我的问题。如果你愿意的话,你可以把它写成关闭这个问题的答案。虽然我很想知道为什么会发生(甚至假设)。 – pror21
绝对不是IntelliJ的错误。首先,最后,永远怀疑自己。 – duffymo