Java 任务 setOnSucceded 不起作用
Java Tasks setOnSucceded does not work
我遇到了类似的问题,但它不起作用。好吧,任务 运行 很好,但是 'setOnSucceeded' 或 'setOnFailed' 永远不会运行。我使用 'ExecutorService'。此外,Programm 永远不会完成,它只是保持 运行。我用 'new Thread(task).start();' 试了一下,然后它很容易构建成功,但是 'setOnSucceeded' 也没有触发。
package Whosebug;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
public class X {
private ExecutorService exec;
public X() {
exec = Executors.newCachedThreadPool();
run();
}
public static void main(String[] args) {
X x = new X();
}
private void run() {
Task<Void> task = new Task<Void>() {
@Override
public void run() {
System.out.println("In Task");
this.succeeded();
}
@Override
protected Void call() throws Exception {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
};
task.setOnSucceeded((WorkerStateEvent event) -> {
System.out.println("In set on Succeded");
});
task.setOnFailed((WorkerStateEvent event) -> {
System.out.println("In Failed");
});
exec.execute(task);
}
}
JavaFX 实用程序 类 的要点是 JavaFX 负责线程等所有工作。因此,您不需要创建任何 ExecutorService
或 Thread
或其他任何内容。另一方面,您需要启动一个 Application
,然后创建一个 Service
,从而创建一个 Task
.
此外,您不需要覆盖 run()
,因为 JavaFX 已经实现了它。逻辑所在的方法是call()
。所以,在所有这些 mambo-jambo 之后,JavaFX 将为您创建 succeeded()
方法。不要手动调用它,因为那样只会造成混乱。另一方面,您可以覆盖它,因此您可以为 succeeded()
挂钩提供另一个选项。
所以,这是代码:
package Whosebug;
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.stage.Stage;
// extending Application
public class X extends Application {
// Empty constructor. I just put it here so we know explicitly that a no-arg construcor exists.
public X() {
// NOP
}
@Override
// a hook for starting the Applicatoin
public void start(Stage primaryStage) {
run();
}
// This is a proper entry point of a JavaFX application
public static void main(String[] args) {
launch(args);
}
private void run() {
// creating a service, then running it
ExampleService service = new ExampleService();
service.start();
}
// this is the dummy service
private static class ExampleService extends Service<Void> {
@Override
protected Task<Void> createTask() {
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
System.out.println("called");
// for Task<Void> we should return null
return null;
}
@Override
protected void succeeded() {
// one hook - overriding
super.succeeded();
System.out.println("Succeded");
}
@Override
protected void failed() {
// one hook - overriding
super.failed();
System.out.println("Failed");
}
};
task.setOnSucceeded((WorkerStateEvent event) -> {
// another hook - callback lambda
System.out.println("In set on Succeded");
});
task.setOnFailed((WorkerStateEvent event) -> {
// another hook - callback lambda
System.out.println("In Failed");
});
return task;
}
}
}
更新
我更改了 start()
和 call()
方法以查看发生了什么:
@Override
public void start(Stage primaryStage) {
System.out.println("--> in start: " + Thread.currentThread().getName());
Thread.dumpStack();
run();
}
@Override
protected Void call() throws Exception {
System.out.println("called in thread: " + Thread.currentThread().getName());
Thread.dumpStack();
return null;
}
start()
通过某种 InvokeLaterDispatcher
从 JavaFX Application Thread
调用。
call()
方法是从 Thread-4
从 java.util.concurrent.ThreadPoolExecutor
调用的。 JavaFX 似乎在异步任务方面设计得特别好。在 Swing 中,我们必须维护我们的线程池。在 JavaFX 中我们不需要,除非我们有 JavaFX 无法处理的特殊需要。我觉得这有可能,但不太可能。
我遇到了类似的问题,但它不起作用。好吧,任务 运行 很好,但是 'setOnSucceeded' 或 'setOnFailed' 永远不会运行。我使用 'ExecutorService'。此外,Programm 永远不会完成,它只是保持 运行。我用 'new Thread(task).start();' 试了一下,然后它很容易构建成功,但是 'setOnSucceeded' 也没有触发。
package Whosebug;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
public class X {
private ExecutorService exec;
public X() {
exec = Executors.newCachedThreadPool();
run();
}
public static void main(String[] args) {
X x = new X();
}
private void run() {
Task<Void> task = new Task<Void>() {
@Override
public void run() {
System.out.println("In Task");
this.succeeded();
}
@Override
protected Void call() throws Exception {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
};
task.setOnSucceeded((WorkerStateEvent event) -> {
System.out.println("In set on Succeded");
});
task.setOnFailed((WorkerStateEvent event) -> {
System.out.println("In Failed");
});
exec.execute(task);
}
}
JavaFX 实用程序 类 的要点是 JavaFX 负责线程等所有工作。因此,您不需要创建任何 ExecutorService
或 Thread
或其他任何内容。另一方面,您需要启动一个 Application
,然后创建一个 Service
,从而创建一个 Task
.
此外,您不需要覆盖 run()
,因为 JavaFX 已经实现了它。逻辑所在的方法是call()
。所以,在所有这些 mambo-jambo 之后,JavaFX 将为您创建 succeeded()
方法。不要手动调用它,因为那样只会造成混乱。另一方面,您可以覆盖它,因此您可以为 succeeded()
挂钩提供另一个选项。
所以,这是代码:
package Whosebug;
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.stage.Stage;
// extending Application
public class X extends Application {
// Empty constructor. I just put it here so we know explicitly that a no-arg construcor exists.
public X() {
// NOP
}
@Override
// a hook for starting the Applicatoin
public void start(Stage primaryStage) {
run();
}
// This is a proper entry point of a JavaFX application
public static void main(String[] args) {
launch(args);
}
private void run() {
// creating a service, then running it
ExampleService service = new ExampleService();
service.start();
}
// this is the dummy service
private static class ExampleService extends Service<Void> {
@Override
protected Task<Void> createTask() {
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
System.out.println("called");
// for Task<Void> we should return null
return null;
}
@Override
protected void succeeded() {
// one hook - overriding
super.succeeded();
System.out.println("Succeded");
}
@Override
protected void failed() {
// one hook - overriding
super.failed();
System.out.println("Failed");
}
};
task.setOnSucceeded((WorkerStateEvent event) -> {
// another hook - callback lambda
System.out.println("In set on Succeded");
});
task.setOnFailed((WorkerStateEvent event) -> {
// another hook - callback lambda
System.out.println("In Failed");
});
return task;
}
}
}
更新
我更改了 start()
和 call()
方法以查看发生了什么:
@Override
public void start(Stage primaryStage) {
System.out.println("--> in start: " + Thread.currentThread().getName());
Thread.dumpStack();
run();
}
@Override
protected Void call() throws Exception {
System.out.println("called in thread: " + Thread.currentThread().getName());
Thread.dumpStack();
return null;
}
start()
通过某种 InvokeLaterDispatcher
从 JavaFX Application Thread
调用。
call()
方法是从 Thread-4
从 java.util.concurrent.ThreadPoolExecutor
调用的。 JavaFX 似乎在异步任务方面设计得特别好。在 Swing 中,我们必须维护我们的线程池。在 JavaFX 中我们不需要,除非我们有 JavaFX 无法处理的特殊需要。我觉得这有可能,但不太可能。