当我通过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;
}
答案 0 :(得分:1)
在JavaFX应用程序上调用onSuceeded
处理程序。这里不应该进行长期运行。最好只在这里进行UI更新。 Task
的结果可用于&#34;发布&#34;操作的结果。可以在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();
}