Java: Wie feststellen ob Task abgearbeitet wurde

Gast #3154539
Lesenswert?

Hallo,

ich stehe mal wieder auf dem Schlauch:

Also in meinem Hauptprogramm kommen folgende Zeilen vor:
1
Runnable task1 = new ps90Suchen();
2
SwingUtilities.invokeLater(task1);

Jetzt möchte ich irgendwie eine Rückmeldung, wenn task1 durchgelaufen 
ist. Ich habe es schon mit variablen versucht, aber das klappt nicht. 
invokeAndWait ebenfalls nicht...

Wie kann ich das Problem lösen?

Holger
Gast #3154553
Lesenswert?

Hallo,

also ich arbeite mit einem COM-Port und rxtccmm. ps9suchen sucht die 
COM-Ports nach dem Gerät durch. Das soll nebenbei laufen. ps90suchen 
greift aber auch auf die gui zu. Z.B. PS90 an COM1 gefunden in einem 
jtetxfield.

rxtxcomm und Swing ist ein ziemlicher Krampf aber ich habe es nun für 
mich perfekt hinbekommen.

Nun möchte ich, nachdem pc90suchen durch ist, ein zweites Gerät suchen. 
Und der Suchvorgang soll auch "nebenbei" laufen, aber erst, wenn ps90 
abgearbeitet ist.


Holger
Persönliche Seite #3154585
Lesenswert?

Naja, zum Krampf wird es halt wenn man es "irgendwie" macht ;-)
Leider schwirren auch einige mäßig gute Beispiel im Netz herum.

Ahnungsloser schrieb:
> Das soll nebenbei laufen
Dann ist invokeLater der völlig falsche Weg, das führt nicht dazu das 
es nebenbei läuft, sondern das du sämliche UI blockierst bis dein Task 
abgearbeitet wurde!


Mach dir für dein suchen zwei SwingWorker, pc90 und ps90,
doInBackground() enthält dabei die Hintergrundarbeit, über  publish 
kannst du Nachrichten an die GUI geben, das Ergbnis ist dein Returnwert.

Diese Nachrichten verarbeitest du in der process() methode verarbeiten, 
das Ergebnis der Hintergrundarbeit in done() mittesl der get() methode 
abfragen.

Dein zweiter Worker benötigt nun eine referenz auf den ersten, und fragt 
in seiner doInBackground() methode das isDone() Flag ab, und legt sich 
bei negativem Ergebnis erst mal schlafen... alternativ startet der erste 
Worker den zweiten solabd er fertig ist.

Das alles ließe sich allerdings an einem Konkretem Codebeispiel sehr 
viel besser erläutern.
Gast #3154649
Lesenswert?

Läubi .. schrieb:
> Dann ist invokeLater der völlig falsche Weg, das führt nicht dazu das
> es nebenbei läuft, sondern das du sämliche UI blockierst bis dein Task
> abgearbeitet wurde!

Moin,

also: GUI wird aufgebaut. Es erscheint: Gerät wird gesucht ...

Dann wird ein Gerät gesucht. Während dieser Zeit ist sowieso nichts mit 
Bedienung der GUI. Während des Suchvorganges werden die 
Schnittsellenbezeichnungen angezeigt. Wenn das Gerät gefunden wurde, 
dann wird die Schnittstelle belegt und dies wird angezeigt. Es läuft in 
vielen Programmen so. Wenn das Gerät aus welchen Gründen nicht gefunden 
wird, dann wird z.B. eine Combobox zur Auswahl der Schnittstelle 
freigegeben.

Aber nun habe ich zum ersten Mal zwei Geräte ...


Holger
Persönliche Seite #3154659
Lesenswert?

Das mag ja alles sein das es "erstmal" so geht, aber du tust das

a) an der falschen Stelle
b) nicht wie gedacht im Hintergrund

Aber da dich das scheinbar eh nicht stört:

SwingUtilities.invokeLater(task1);
SwingUtilities.invokeLater(task2);

Führt Task2 dann aus wenn Task1 abgeschlossen ist (oder etwas später). 
Aber wie gesagt: schlechtes Design und früher oder später kommt man 
damit in die Bedrulie....

Ahnungsloser Holger schrieb:
> Während dieser Zeit ist sowieso nichts
> mit Bedienung der GUI
Auch das Neuzeichen geht nicht, ggf. blockierst du sogar das Beenden des 
Programms... in kleinem Rahmen mag das gehen, wozu dann aber explizit 
zwei Tasks wenn eh beide nacheinander ablaufen sollen?
Gast #3154686
Lesenswert?

Moin,

nun lass es mal egals sein was nun richtig oder falsch ist und ob es 
funktioniert oder nicht oder sonst was.

Die Frage ist ja, wie bekomme ich folgendes hin, wobei task1 beendet 
sein muss bevor task2 starten darf:
1
Runnable task1 = new ps90Suchen();
2
SwingUtilities.invokeLater(task1);


1
Runnable task2 = new ps91Suchen();
2
SwingUtilities.invokeLater(task2);



Holger
Persönliche Seite #3154975
Lesenswert?

Schreib ich doch oben, das macht genau das, erst wird Task1 
abgearbeitet, dann Task2.
Wie ich oben schon schrieb startest du damit keinen Hintergrundthread, 
sondern reihst deine Aufgabe nur in die "Abarbeitungsqueue" des 
GUI-Threads ein, der all diese Aufgaben nacheinander abarbeitet (deshalb 
kann es sein, dass nach task1 noch andere Aufgaben anstehen die erst 
ausgeführt werden, es wird aber auf jedenfall erst Task2 abgearbeitet 
nachdem Task1 abgeschlossen ist).

Falls das "nicht so funktioniert" wie du dir das denkst müsste man mehr 
Code sehen. Wenn da z.B. Callbacks im Spiel sind müsste ggf. Task1 den 
Task2 als Konstruktorparameter kriegen und "am Ende" starten.
Gast #3155726
Lesenswert?

Läubi .. schrieb:
> Dein zweiter Worker benötigt nun eine referenz auf den ersten, und fragt
> in seiner doInBackground() methode das isDone() Flag ab, und legt sich
> bei negativem Ergebnis erst mal schlafen... alternativ startet der erste
> Worker den zweiten solabd er fertig ist.

Moin,

so, habe jetzt mal auf SwingWorker umgestellt;-) Danke!


Nun habe ich noch eine Frage: Wie mache ich das mit der Referenz?



Gruß
Ahnungsloser Holger
Persönliche Seite #3155777
Lesenswert?

Datentypen musst du ggf. anpassen...
1
 private static final class SwingWorker1 extends SwingWorker<String, String> {
2
        private final SwingWorker<?, ?> otherWorker;
3

4
        public SwingWorker1(SwingWorker<?, ?> otherWorker) {
5
            this.otherWorker = otherWorker;
6
        }
7

8
        @Override
9
        protected String doInBackground() throws Exception {
10
            return "Fertig 1";
11
        }
12

13
        @Override
14
        protected void done() {
15
            otherWorker.execute();
16
            //Tu was sonst so anliegt...
17
        }
18
    }
19

20
    private static final class SwingWorker2 extends SwingWorker<String, String> {
21
        @Override
22
        protected String doInBackground() throws Exception {
23
            return "Fertig 2";
24
        }
25
    }
26

27
    public static void main(String[] args) {
28
        SwingWorker2 sw2 = new SwingWorker2();
29
        SwingWorker1 sw1 = new SwingWorker1(sw2);
30
        sw1.execute();
31
    }

Bernd schrieb:
> Da kann man sich benachrichtigen lassen wenn der
> Task abgearbeitet wurde
Referenz? Man kann dort auch mit Futures arbeiten, was aber keine 
Benachrichtigung enthält... ansonsten ist ein SwingWorker (auch) ein 
Future...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren