2015-11-13 11 views
6

Ich habe ein GUI-Programm, das TestNG Automation Skripte ausführt. Es ist für Benutzer gedacht, einige Einstellungen einfach zu konfigurieren und das gewünschte Automatisierungsskript zu starten.Stoppen eines laufenden Prozesses über GUI, in Java

Eine Sache, die ich hinzufügen muss, ist die Fähigkeit, den laufenden TestNG-Prozess sofort zu stoppen. So etwas wie in Eclipse, der Button "Beenden" stoppt sofort, was gerade läuft.

Dies ist, was der Code, der die TestNG Tests aussieht startet:

public class ScriptRunner implements Runnable { 

    public void runScript() { 
     Thread testRun = new Thread(this); 
     testRun.start(); 
    } 

    @Override 
    public void run() { 
     //various other things are configured for this, 
     //but they're not relevant so I left them out 
     TestNG tng = new TestNG(); 

     //While this runs, various browser windows are open, 
     //and it could take several minutes for it all to finish 
     tng.run(); 
    } 
} 

Gemäß dem Kommentar, der tng.run() mehrere Minuten dauern kann zu vollenden, und es mehrere Dinge, Öffnen/Schließen Browserfenster durchführen, etc.

Wie kann ich den Prozess einfach sofort beenden, wie wenn Sie eine Anwendung von einer IDE aus ausführen würden?

EDIT:

Per Kommentare, bin ich versucht, eine ServiceExecutor und shutDownNow() Der Code zu verwenden, wird wie folgt aussehen: wird

ExecutorService executorService = Executors.newFixedThreadPool(10); 

public void runScript() { 
    executorService.execute(this); 
} 

//this method gets called when I click the "stop" button 
public void stopRun() { 
    executorService.shutdownNow(); 
} 

@Override 
public void run() { 
    //same stuff as from earlier code 
} 
+0

System.exit (0); beendet die JVM sofort – Olu

+0

@OluCode Ja, aber wird das nicht auch meine GUI-Anwendung zu töten? Ich brauche eine Möglichkeit, um das laufende TestNG-Objekt einfach zu töten. – Andrio

+1

Wenn es ein Thread ist, verwenden Sie einen Thread-Manager wie ExecutorService, um die Thread-Lebensdauer für Sie zu behandeln, und rufen Sie serviceObject.shutDownNow() auf; – Olu

Antwort

1

Ich habe kürzlich am Executor-Framework gearbeitet. Hier habe ich mein Problem http://programtalk.com/java/executorservice-not-shutting-down/

aufgeführt Seien Sie vorsichtig, wenn Sie einige IO-Operationen ausführen, kann der Executor-Dienst nicht sofort herunterfahren. Wenn Sie den folgenden Code sehen, ist stopThread wichtig, da es Ihrem Programm mitteilt, dass der Thread angehalten wurde. Und Sie können eine Wiederholung stoppen, was Sie tun. werde ich Code wie folgt ändern:

public class MyClass { 

private ExecutorService executorService; 

private boolean stopThread = false; 

public void start() { 
    // gives name to threads 
    BasicThreadFactory factory = new BasicThreadFactory.Builder() 
      .namingPattern("thread-%d").build(); 
    executorService = Executors.newSingleThreadExecutor(factory); 
    executorService.execute(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       doTask(); 
      } catch (Exception e) { 
       logger.error("indexing failed", e); 
      } 

     } 
    }); 
    executorService.shutdown(); 
} 

private void doTask() { 
    logger.info("start reindexing of my objects"); 
    List<MyObjects> listOfMyObjects = new MyClass().getMyObjects(); 
    for (MyObjects myObject : listOfMyObjects) { 
     if(stopThread){ // this is important to stop further indexing 
      return; 
     } 
     DbObject dbObjects = getDataFromDB(); 
     // do some task 
    } 
} 



public void stop() { 
    this.stopThread = true; 
    if(executorService != null){ 
     try { 
      // wait 1 second for closing all threads 
      executorService.awaitTermination(1, TimeUnit.SECONDS); 
     } catch (InterruptedException e) { 
      Thread.currentThread().interrupt(); 
     } 
    } 
} 

}

3

Spawn ein Kind JVM-Prozess unter Verwendung von Process oder Runtime und Sie in der Lage sein, diesen Prozess zu beenden, wenn der Benutzer anfordert, dass das Skript nicht mehr ausgeführt wird.

1

speichern alle erstellten Prozesse und töten sie, wenn Ihr Programm endet:

public class ProcessFactory { 
    private static Set<Process> processes = new HashSet<>(); 
    private static boolean isRunning = true; 

    public static synchronized Process createProcess(...) throws ... { 
    if (!isRunning) 
     throw ... 
    ... // create your spawned process 
    processes.add(process); 
    return process; 
    } 

    public static synchronized void killAll() { 
    isRunning = false; 
    for (Process p : processes) 
     p.destroy(); 
    processes.clear(); 
    } 

    public static void registerShutdownHook() { 
     Runtime.getRuntime().addShutdownHook(new Thread() { 
     void run() { 
      killAll(); 
     } 
     }); 
    } 
} 

Dies wird durch das Hinzufügen eines Mechanismus verbessert werden kann, die bereits tot Prozesse entfernt, aber Sie die allgemeine Idee.

2

Sie können ExecutorService verwenden, um die Testausführung in einem anderen Thread zu starten. Sie können wählen, ob Sie mehrere Threads parallel oder nur einen Thread für alle Tests nacheinander verwenden möchten, indem Sie den gewünschten Executor-Service auswählen.

Starten Sie danach die Ausführung aller Tests in derselben Executor-Service-Instanz, indem Sie die Methode submit() aufrufen. Sie können die Ausführung aller übergebenen Runnables stoppen, indem Sie die Methode shutdownNow() aufrufen.

Es ist wichtig, die gleiche Instanz von ExecutorService zu verwenden, andernfalls starten Sie jeden Test in einem anderen Thread, und Sie können nicht die Ausführungskette unterbrechen (oder auf allen shutdownNow() aufrufen).

1

Was darüber, einen flüchtigen statischen boolean hinzufügen und die Thread-Code aussieht wie machen ...

if(ScriptRunner.runThread){ 
    //Do some stuff here 
} 
if(ScriptRunner.runThread){ 
    //Do some other stuff here 
} 
if(ScriptRunner.runThread){ 
    //Do some other stuff here 
} 
if(ScriptRunner.runThread){ 
    //Do rest of the stuff here 
} 

Jetzt können Sie auf eine Schaltfläche in Ihrem Haupt-GUI hinzufügen, die die runThread auf false so einfach stellen die Der Thread wird fast sofort beendet, und der übrige Code bleibt unberührt, wenn Sie auf die Schaltfläche Stop drücken.

public class ScriptRunner implements Runnable { 

    volatile static Boolean runThread = true; 

    public void runScript() { 
     Thread testRun = new Thread(this); 
     testRun.start(); 
    } 

    public void terminate(){ 
     runThread = false; 
    } 

    @Override 
    public void run() { 
     //various other things are configured for this, 
     //but they're not relevant so I left them out 
     TestNG tng = new TestNG(); 

     //While this runs, various browser windows are open, 
     //and it could take several minutes for it all to finish 
     tng.run(); 
    } 
} 
1

Wie wäre es mit einem neuen Thread?Sie haben eine private Thread thread; in der gui hinzuzufügen und wann immer Sie

thread = new thread(){ 
    @Override 
    public void run(){ 
     //start process here 
    } 
}; 
thread.start(); 

und zu stoppen „beenden“

thread.stop(); (depracted) oder thread.setDeamon(true);

Jedesmal, wenn ich einen Prozess zu stoppen, indem das müssen anfangen gui das benutze ich.

Hoffe, dass ich helfen konnte;)

1

In Ihrem GUI irgendwo haben Sie so etwas wie

ScriptRunner scriptRunner = new ScriptRunner(); 
scriptRunner.runScript(); 

Wenn Sie wollen, dass es

scriptRunner.interrupt(); 

Ändern Sie den Code in Script

rufen stoppen
private Thread testRun; 
public void runScript() { 
    testRun = new Thread(this); 
    testRun.start(); 
} 

public void interrupt() { 
    testRun.interrupt(); 
} 
Verwandte Themen