Programm abbrechnen aus Progressdialog (and. Thread)

Klassen, Objekte, Methoden, Instanzen

Moderator: Moderatoren

Antworten
henxl
UDF-Programmierer
UDF-Programmierer
Beiträge: 91
Registriert: Fr, 10. Feb 2006 19:46
Wohnort: Mannheim

Programm abbrechnen aus Progressdialog (and. Thread)

Beitrag 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
Das einzige, was ich weiß ist, dass ich nichts weiß, Sokrates
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16509
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag 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
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16509
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag 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
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
henxl
UDF-Programmierer
UDF-Programmierer
Beiträge: 91
Registriert: Fr, 10. Feb 2006 19:46
Wohnort: Mannheim

Beitrag 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
Das einzige, was ich weiß ist, dass ich nichts weiß, Sokrates
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Beitrag 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 ...
gruss by OHR
Jimmy
henxl
UDF-Programmierer
UDF-Programmierer
Beiträge: 91
Registriert: Fr, 10. Feb 2006 19:46
Wohnort: Mannheim

Beitrag 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
Das einzige, was ich weiß ist, dass ich nichts weiß, Sokrates
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Beitrag 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.) } )
gruss by OHR
Jimmy
henxl
UDF-Programmierer
UDF-Programmierer
Beiträge: 91
Registriert: Fr, 10. Feb 2006 19:46
Wohnort: Mannheim

Beitrag 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
Das einzige, was ich weiß ist, dass ich nichts weiß, Sokrates
Antworten