PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SWT asyncExec Problem !?!



leonReif
04-06-2005, 14:23
:confused:

Hallo zusammen,

ich habe die Beiträge zu diesem Thema gelesen, aber ich komme einfach nicht weiter! Ich glaube Ihr habt mehr Erfahrungen mit SWT.

Ich würde gerne in einem anderen Thread ein Progressbar anzeigen, während ich Daten aus einer Datenbank lese. Wenn die Daten da sind, dann schalte ich die Progressbar ab.

Der Thread, der die Progressbar anzeigen soll bleibt hängen, bis die Tabelle mit Daten gefüllt ist, dann läuft der Thread erst !?!

Die ProgressBar startet eigentlich selber einen Thread! Indem man die Klasse allokiert! Oder ? Wenn ich z.B. einfach eine ProgressBar in einer Composite anzeige, dann läuft automatisch!

ich bin für jede antwort dankbar!!!

Z.B.

MyProgressBar.start();

fillTable();

MyProgressBar.stop();

Hier ist der Code:

public static void start(final Shell aShell)
{
final Shell shell = new Shell(aShell);
shell.setLayout(new FillLayout());
ProgressBar bar = new ProgressBar(shell, SWT.INDETERMINATE);
bar.setSize(500, 20);
shell.setSize(300, 400);

shell.pack();
shell.open();

thread = new Thread(new Runnable() {
public void run()
{
while (! shell.isDisposed()) {

Display.getDefault().asyncExec(new Runnable() {
public void run()
{
bar.setSelection(bar.getSelection()+1);
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();

peschmae
04-06-2005, 16:58
Willkommen zur allwöchentlichen SWT-(a)syncexec Fragestunde mit peschmae :D

Das Auslesen der Daten aus der Datenbank geschieht wo genau? In einem separaten Thread? Oder im Hauptthread?

MfG Peschmä

leonReif
04-06-2005, 17:58
Hallo Peschmae,

Das Auslesen der Daten aus der Datenbank geschieht im Hauptthread. Dafür habe ich keinen extra Thread definiert!

Wenn der User die Enter-Taste drückt, dann rufe ich meine find Methode auf.
In meiner find Methode rufe ich dann die ProgressBar auf.

mTextFind.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e) {

if(e.keyCode == SWT.CR)
{
find();
}
}

});

find()
{
MyProgressBar.start();
datenLaden .....
MyProgressBar.stop();
}

Vielen Dank :)

peschmae
04-06-2005, 19:34
Dann überrascht mich das nicht dass das nicht geht.

Der Grund ist folgender: Sachen wie Neuzeichnen von Fenstern oder Ausführen von Runnables die du asyncexec oder syncexec übergibst geschieht in der Nachrichtenverarbeitungsschleife. Während dem display.readanddispatch() oder wie das auch immer heisst.

Wenn du nun im Hauptthread eine lang dauernde Aktion ausführst - z.B. lesen aus der Datenbank - dann wird so lange die Nachrichtenverarbeitungsschleife nicht durchlaufen - d.h. unter anderem mit asyncexec von einem anderen Thread übergebene Sachen werden nicht ausgeführt...

Eine - allerdings eher unsaubere - Möglichkeit wäre auch z.B. während des Einlesens ab und zu mal display.readAndDispatch() aufzurufen, um eventuelle Events abzuarbeiten.

MfG Peschmä

leonReif
04-06-2005, 20:08
Hi!

Also es hört sich so an, dass da keine saubere Lösung dafür gibt!

Schade, dass SWT keine richtige Lösung dafür bietet!

Ich werde auf ProgressBar verzichten und einfach nur ein animieters Gif-Bild anzeigen.

leonReif
04-06-2005, 22:10
Hallo Peschmae,

>Eine - allerdings eher unsaubere - Möglichkeit wäre auch z.B. während des >Einlesens ab und zu mal display.readAndDispatch() aufzurufen, um >eventuelle Events abzuarbeiten.

Es funktioniert tatsächlich, wenn ich in der Schleife, wo ich die Daten aus der Datenbank lese display.readAndDispatch() aufrufe, wobei kann passieren, dass display.readAndDispatch() irgendwann mal 20000 mal aufgerufen wird. Je nachdem wieviel Datensätze ich lese!

Ich werde nicht so schnell aufgeben. Ich werde mir eine saubere Lösung ausdenken.

Ich danke dir :)

peschmae
05-06-2005, 10:11
Du tust halt das Datenbanklesen in einen Thread und machst alle Gui-Änderungen die du dort machen musst via (a)syncExec...

MfG Peschmä

leonReif
05-06-2005, 11:08
Hi!

Da hast du recht. Danke für deinen Tipp :)

Technaton
05-06-2005, 15:58
Sag mal, Onkel peschmä, mal ne generelle Frage zu dem Thema:

Je nach Applikation kann mir sowas ja öfter passieren -- eine Konfiguarationsdatei wird eingelesen oder geschrieben, eine Datenbank ausgelesen, und so weiter.

Damit mein Programm in der Zeit nicht anhält, werd ich wohl dauernd irgendwelche Threads erschaffen müssen, oder? Und, wenn ja, wie lautet denn die kürzeste Form, um ein paar Zeilen (z.B. eine aufwendige Enumeration) in einen eigenen Thread zu packen?

peschmae
05-06-2005, 16:31
Je nach Applikation kann mir sowas ja öfter passieren -- eine Konfiguarationsdatei wird eingelesen oder geschrieben, eine Datenbank ausgelesen, und so weiter.


Naja, Konfigurationsdatei sollte ja nicht lange gehen... ;)



Damit mein Programm in der Zeit nicht anhält, werd ich wohl dauernd irgendwelche Threads erschaffen müssen, oder?

Ja, mehr oder weniger. Wenn die Aufgabe gut zerstückelbar ist kann die Variante mit readAndDispatch() selber aufrufen durchaus brauchbar sein.


Und, wenn ja, wie lautet denn die kürzeste Form, um ein paar Zeilen (z.B. eine aufwendige Enumeration) in einen eigenen Thread zu packen?

Ähm, tja. Das letzte mal Java ist schon *ewig* her. Das kürzeste dürfte wohl eine anonyme innere Klasse sein bei der du gleich die run() (ode rwar das start()?) Methode aufrufst.

Viel mühsamer als das erstellen von Threads ist aber das Aktualisieren der Gui mit (a)syncexec jedes mal wenn du aus dem Thread was ändern willst ;)

MfG Peschmä