如何在后台线程中正确停止 sikuli?
How to properly stop sikuli in background thread?
我在后台线程中有简单的 sikuli 等待操作:
public static void main(String[] args) {
Runnable rn = () -> {
Screen s = new Screen();
try {
s.wait(imgPattern, 5);
} catch (FindFailed e) {
e.printStackTrace();
}
System.out.println("Finished wait.");
};
Thread th = new Thread(rn);
th.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
}
th.interrupt();
try {
th.join();
} catch (InterruptedException e) {
}
System.out.println("Finished main.");
}
当我尝试中断和停止后台线程时,我得到了 java.lang.InterruptedException,但 sikuli 仍然有效。这是程序的输出:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at java.awt.Robot.delay(Unknown Source)
at org.sikuli.script.RobotDesktop.delay(RobotDesktop.java:240)
at java.awt.Robot.autoDelay(Unknown Source)
at java.awt.Robot.afterEvent(Unknown Source)
at java.awt.Robot.mouseMove(Unknown Source)
at org.sikuli.script.RobotDesktop.doMouseMove(RobotDesktop.java:61)
at org.sikuli.script.RobotDesktop.smoothMove(RobotDesktop.java:165)
at org.sikuli.script.RobotDesktop.smoothMove(RobotDesktop.java:145)
at org.sikuli.script.Mouse.move(Mouse.java:361)
at org.sikuli.script.Mouse.move(Mouse.java:331)
at org.sikuli.script.Mouse.init(Mouse.java:60)
at org.sikuli.script.Screen.initScreens(Screen.java:107)
at org.sikuli.script.Screen.<clinit>(Screen.java:72)
at SikuliTest.lambda[=11=](SikuliTest.java:12)
at java.lang.Thread.run(Unknown Source)
FindFailed: /C:/imgPatternPath.png: (18x14) in S(0)[0,0 1366x768] E:Y, T:3,0
Line 2759, in file Region.java
at org.sikuli.script.Region.wait(Region.java:2759)
Finished wait.
Finished main.
at SikuliTest.lambda[=11=](SikuliTest.java:14)
at java.lang.Thread.run(Unknown Source)
如何正确停止 sikuli 工作?
关于中断的工作原理可能有些混淆。引用 this 回答,
Thread.interrupt()
sets the interrupted flag of the target thread.
Then code running in that target thread MAY poll the interrupted
status and handle it appropriately. Some methods that block such as
Object.wait()
may consume the interrupted status immediately and throw
an appropriate exception (usually InterruptedException
)
Interruption in Java is not pre-emptive. Put another way both threads
have to cooperate in order to process the interrupt properly. If the
target thread does not poll the interrupted status the interrupt is
effectively ignored.
Polling occurs via the Thread.interrupted()
method which returns the
current thread's interrupted status AND clears that interrupt flag.
Usually the thread might then do something such as throw
InterruptedException
.
这意味着Sikuli wait
可能没有正确处理中断(没有轮询中断状态)并保持运行正常
实际上 Sikuli 使用 Robot.delay()
,这与 Thread.sleep()
不同 - 忽略了 InterruptedException
.
你可以做的是创建一个Process
到运行的Sikuli自动化,你可以通过调用sikuliProcess.destroy()
来终止它
我在后台线程中有简单的 sikuli 等待操作:
public static void main(String[] args) {
Runnable rn = () -> {
Screen s = new Screen();
try {
s.wait(imgPattern, 5);
} catch (FindFailed e) {
e.printStackTrace();
}
System.out.println("Finished wait.");
};
Thread th = new Thread(rn);
th.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
}
th.interrupt();
try {
th.join();
} catch (InterruptedException e) {
}
System.out.println("Finished main.");
}
当我尝试中断和停止后台线程时,我得到了 java.lang.InterruptedException,但 sikuli 仍然有效。这是程序的输出:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at java.awt.Robot.delay(Unknown Source)
at org.sikuli.script.RobotDesktop.delay(RobotDesktop.java:240)
at java.awt.Robot.autoDelay(Unknown Source)
at java.awt.Robot.afterEvent(Unknown Source)
at java.awt.Robot.mouseMove(Unknown Source)
at org.sikuli.script.RobotDesktop.doMouseMove(RobotDesktop.java:61)
at org.sikuli.script.RobotDesktop.smoothMove(RobotDesktop.java:165)
at org.sikuli.script.RobotDesktop.smoothMove(RobotDesktop.java:145)
at org.sikuli.script.Mouse.move(Mouse.java:361)
at org.sikuli.script.Mouse.move(Mouse.java:331)
at org.sikuli.script.Mouse.init(Mouse.java:60)
at org.sikuli.script.Screen.initScreens(Screen.java:107)
at org.sikuli.script.Screen.<clinit>(Screen.java:72)
at SikuliTest.lambda[=11=](SikuliTest.java:12)
at java.lang.Thread.run(Unknown Source)
FindFailed: /C:/imgPatternPath.png: (18x14) in S(0)[0,0 1366x768] E:Y, T:3,0
Line 2759, in file Region.java
at org.sikuli.script.Region.wait(Region.java:2759)
Finished wait.
Finished main.
at SikuliTest.lambda[=11=](SikuliTest.java:14)
at java.lang.Thread.run(Unknown Source)
如何正确停止 sikuli 工作?
关于中断的工作原理可能有些混淆。引用 this 回答,
Thread.interrupt()
sets the interrupted flag of the target thread. Then code running in that target thread MAY poll the interrupted status and handle it appropriately. Some methods that block such asObject.wait()
may consume the interrupted status immediately and throw an appropriate exception (usuallyInterruptedException
)Interruption in Java is not pre-emptive. Put another way both threads have to cooperate in order to process the interrupt properly. If the target thread does not poll the interrupted status the interrupt is effectively ignored.
Polling occurs via the
Thread.interrupted()
method which returns the current thread's interrupted status AND clears that interrupt flag. Usually the thread might then do something such as throwInterruptedException
.
这意味着Sikuli wait
可能没有正确处理中断(没有轮询中断状态)并保持运行正常
实际上 Sikuli 使用 Robot.delay()
,这与 Thread.sleep()
不同 - 忽略了 InterruptedException
.
你可以做的是创建一个Process
到运行的Sikuli自动化,你可以通过调用sikuliProcess.destroy()