如何在后台线程中正确停止sikuli?

时间:2017-05-27 12:18:01

标签: java multithreading sikuli

我在后台线程中有简单的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$0(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$0(SikuliTest.java:14)
    at java.lang.Thread.run(Unknown Source)

如何正确阻止sikuli工作?

2 个答案:

答案 0 :(得分:1)

关于中断如何工作可能会有一些混乱。引自this回答,

  

Thread.interrupt()设置目标线程的中断标志。   然后在该目标线程中运行的代码可以轮询中断的   状态并适当地处理它。阻止的一些方法如   Object.wait()可能会立即消耗中断状态并抛出   适当的例外(通常为InterruptedException

     

Java的中断不是先发制人。换一种方式两个线程   必须合作才能正确处理中断。如果   目标线程不会轮询中断所处的中断状态   实际上被忽略了。

     

通过返回的Thread.interrupted()方法进行轮询   当前线程的中断状态并清除该中断标志。   通常,线程可能会执行诸如throw之类的操作   InterruptedException

这意味着Sikuli wait可能无法正确处理中断(不轮询中断状态)并保持正常运行。

答案 1 :(得分:0)

实际上Sikuli使用Robot.delay(),与Thread.sleep()不同的是,Sikuli忽略了InterruptedException

您可以做的是创建一个Process来运行Sikuli自动化,您可以通过调用sikuliProcess.destroy()

终止它