Seite 1 von 1

Programm abbrechnen aus Progressdialog (and. Thread)

Verfasst: Sa, 28. Jun 2008 21:37
von henxl
Hallo,

das Programm ist mit Auswertungen beschäftigt. Während dessen läuft ein Progressdialog in einem anderen Thread. In diesem Progressdialog will ich den ursprünglichen Programmteil (Auswertungen) abbrechen.

Ein BREAK in dem Progressdialog beendet aber nur den Thread (und die Progressanzeige). Das ursprüngliche Programm (Auswertungen) läuft weiter.

Gibt es eine Möglichkeit, das ursprüngliche Programm (Auswertungen) aus dem Progressthread heraus abzubrechen ?

Grüße
Heinz

Verfasst: So, 29. Jun 2008 1:56
von Martin Altmann
Hallo Heinz,
erzeuge Dir in der Klasse, die die Auswertung macht, doch einfach eine Variable, die Du permanent bei der Auswertung prüfst.
Sobald sie .t. ist, wird die Auswertung abgebrochen - initialisieren musst Du sie dann natürlich mit .f.
Das Setzen der Variable kannst Du ja dann aus dem anderen Thread heraus vornehmen.
Bsp:

Code: Alles auswählen

CLASS Auswertung .....
  VAR AuswertungAbbrechen
....
::AuswertungAbbrechen := .f.
Progress( [color=red]self[/color] ):New()
do while ... .and. .not. ::AuswertungAbbrechen
....
enddo
....
und in Deiner Progress-Klasse setzt Du dann halt beim Abbruch die Variable entsprechend - das Objekt hast Du ja beim Aufruf oben als Parameter übergeben:

Code: Alles auswählen

...
oObjekt:AuswertungAbbrechen := .t.
...
Viele Grüße,
Martin

Verfasst: So, 29. Jun 2008 8:22
von Martin Altmann
oder noch besser - und gleich richtig sauber:
Die Variable HIDDEN und eine Methode (exported), die die Variable dann auf .f. setzt und von außen aufgerufen wird.

Viele Grüße,
Martin

Verfasst: So, 29. Jun 2008 11:20
von henxl
Hallo Martin,

vielen Dank für Deinen Tipp.

Das Problem ist allerdings, dass das Programm Auswertungen nicht in einer Schleife läuft. Es besteht aus ca. 1000 Programmzeilen und enthält innerhalb der 1000 Programmzeilen Schleifen. Ich müsste also ständig (im modalen Programmcode und in den Schleifen) die Variable "AuswertungAbbrechen" abfragen.
So ähnlich hatte ich es bisher realisiert, nämlich bei der Aktualisierung der Progressanzeige aus dem Programm Auswertungen heraus. Da diese nur sporadisch erfolgte, konnte es schon mal eine Minute dauern, bis der Abbruch vollzogen wurde. Das dauert mir aber zu lange.

Vielleicht gibt es doch eine weniger aufwendige Lösung.

Zum Beispiel habe ich mit einem "PostAppEvent" aus dem Progressdialog an den Auswertungsdialog herumprobiert, aber es funktioniert nicht.

...

Grüße
Heinz

Verfasst: So, 29. Jun 2008 21:47
von AUGE_OHR
hi,
henxl hat geschrieben: Zum Beispiel habe ich mit einem "PostAppEvent" aus dem Progressdialog an den Auswertungsdialog herumprobiert, aber es funktioniert nicht.
was funktioniert nicht ?
sendest du einen UserDef Event ?

eigendlich sollte es kein Problem sein ...

Verfasst: So, 29. Jun 2008 21:59
von henxl
Hallo Jimmy,

ich sende im Thread B folgenden Befehl an die Eventloop von Thread A

Code: Alles auswählen

PostAppEvent( xbeU_Exe, { || Break(.F.) } , , oAltDlg )
xbeU_Exe ist eine selbstdefinierte Konstante, die in der Eventloop von Thread A abgefragt wird. oAltDlg ist der den Thread B aufrufende Dialog (Thread A), der als Variable übergeben wird.
Danach wird Thread B sofort beendet.

In Thread A kommt dieses "PostAppEvent" nicht an, jedenfalls reagiert das Programm nicht darauf.

Grüße
Heinz

Verfasst: Mo, 30. Jun 2008 10:56
von AUGE_OHR
hi,
henxl hat geschrieben: ich sende im Thread B folgenden Befehl an die Eventloop von Thread A

Code: Alles auswählen

PostAppEvent( xbeU_Exe, { || Break(.F.) } , , oAltDlg )
xbeU_Exe ist eine selbstdefinierte Konstante, die in der Eventloop von Thread A abgefragt wird. oAltDlg ist der den Thread B aufrufende Dialog (Thread A), der als Variable übergeben wird.
Danach wird Thread B sofort beendet.

In Thread A kommt dieses "PostAppEvent" nicht an, jedenfalls reagiert das Programm nicht darauf.
ist Thread A der Owner von Thread B ?
nur wenn Thread A der Parent oder mindestens der Owner ist "kümmert"
er sich "darum" ansonsten "ignoriert" er es. Ein "default" SetAppWindow()
muss nicht immer der Owner sein und ist meistens nicht der Parent.

warum gibts du den Codeblock, der nicht "dort" ausgedührt wird, im
PostappEvent() als 2nd. Parameter an ? Es reicht doch der 1st und 4th
den der 2nd würde ja immer für ein ".F." stehen.

Der Codeblock sollte nun "da stehen wo der Event gefragt wird", also in
Thread A mit dem 1st. Event loop ( dem du das schicken willst, oder
genau anderrum ... ? )

Code: Alles auswählen

PostAppEvent( xbeU_Exe, , , oMain_A )

Thread mit oMain_A

DO CASE
     CASE nEvent = xbeU_Exe
         EVAL( { || Break(.F.) } )

Verfasst: Di, 01. Jul 2008 12:40
von henxl
Hallo Jimmy,

erstmals vielen Dank, dass Du Dir die Mühe machst und Dich mit meinem Problem beschäftigst.

Ich habe es inzwischen durch Änderung des Parent bzw. des Owner geschafft, dass der "PostAppEvent"-Befehl in der Eventloop des Thread A ankommt.
Durch Hinzufügen eines MsgBox"...") sehe jetzt, wann der im "PostAppEvent"-Befehl übergebene Codeblock in der Eventloop des Thread A ausgeführt wird:
Und zwar erst dann, wenn das ganze Programm Auswertungen abgearbeitet ist.

Ich möchte jedoch, dass der übergebene Codeblock ( { || Break(.F.) } sofort ausgeführt und das Programm Auswertungen damit abgebrochen wird.

Übrigens: den Codeblock übergebe ich als Parameter im "PostAppEvent"-Befehl, um die Eventloop möglichst übersichtlich zu halten. Somit kann ich die User-Konstante "xbeU_Exe" mehrfach verwenden.

...

Grüße
Heinz