我正在尝试创建一个网络javafx应用程序并在任务中运行serverloop。因为ServerSocket接受方法是阻塞的,并且我无法测试任务是否被取消(使用isCancelled())。
我当前的实施:
class ServerTask extends Task<Void> {
ExecutorService executorService;
final int PORT = 12345;
@Override
protected Void call() throws Exception {
executorService = Executors.newFixedThreadPool(8);
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
while (true)
{
executorService.execute(
new Client(serverSocket.accept()));
}
}
catch (IOException e) {
System.out.print(e.getMessage());
}
return null;
}
}
当在某个任务上调用chancel或者我在javafx应用程序中实现serverloop的方法错误时,是否有可能覆盖或捕获事件?如果是这样,应该怎么做?
答案 0 :(得分:1)
一旦Task
被调用,CANCELLED
就会转换为cancel()
状态,即使call()
方法仍然被阻止运行不间断方法。
通过关闭套接字可以有效地“中断”ServerSocket
,这将导致当前被阻止的任何accept()
方法以IOException
终止。
所以你可以这样做:
class ServerTask extends Task<Void> {
ExecutorService executorService;
final int PORT = 12345;
private ServerSocket serverSocket ;
@Override
protected Void call() throws Exception {
executorService = Executors.newFixedThreadPool(8);
try (serverSocket = new ServerSocket(PORT)) {
while (true)
{
executorService.execute(
new Client(serverSocket.accept()));
}
}
catch (IOException e) {
if (isCancelled()) {
System.out.println("Cancelled");
} else {
System.out.print(e.getMessage());
}
}
return null;
}
@Override
protected void cancelled() {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException exc) {
exc.printStackTrace();
}
}
}
}
这是一个非常快速的完整示例:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class NonIterruptableTaskCancellation extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
ServerSocket socket = new ServerSocket(2048);
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
while (! isCancelled()) {
try {
Socket s = socket.accept();
System.out.println("Connected to "+s);
s.close();
} catch (IOException exc) {
if (isCancelled()) {
System.out.println("Cancelled");
} else {
System.out.println("Unexpected IO Exception");
throw exc ;
}
}
}
return null ;
}
@Override
protected void cancelled() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread t = new Thread(task);
t.setDaemon(true);
t.start();
Label label = new Label();
label.textProperty().bind(task.stateProperty().asString());
Button cancel = new Button("Cancel");
cancel.disableProperty().bind(task.runningProperty().not());
cancel.setOnAction(e -> task.cancel());
VBox root = new VBox(5, label, cancel);
root.setPadding(new Insets(10));
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 200, 120);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}