Anderen Thread beenden

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Antworten
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Anderen Thread beenden

Beitrag von Jan »

Kann mir jemand sagen, wie ich einen bestimmten Thread aus einem anderen heraus beenden kann? Ich kann den mit dem Threadnamen identifizieren, aber ich glaube, das hilft nicht. Aber anhand dem könnte ich den halt identifizieren (was ist das eigentlich für ein Deutsch? :? ).

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

Re: Anderen Thread beenden

Beitrag von Martin Altmann »

Jan,
Du musst in dem Thread einfach eine Methode haben (z.B. :stop()), die (im Prinzip) ein quit aufruft.
Und diese Methode rufst Du von außen auf.

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
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von Jan »

Hallo Martin,

soweit war ich auch schon :| Und wie rufe ich die Methode für genau diesen Thread von außen auf?

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

Re: Anderen Thread beenden

Beitrag von Martin Altmann »

Nun,
ich denke, Du weißt den Threadnamen? Dann einfach oThread:stop()!
Anbei mal mein animierter Mauszeiger:

Code: Alles auswählen

CLASS RunDog FROM Thread
	PROTECTED:
		VAR terminated
    VAR aniAct
	EXPORTED:
		 VAR workCounter

		 INLINE METHOD init
				::Thread:init()
				::terminated  := .F.
				::aniAct := 1010
		 RETURN self

		 INLINE METHOD stop

		 RETURN ( ::terminated := .T. )

		 METHOD execute, checkTermination
ENDCLASS

// Diese Methode wird im Thread ausgeführt
METHOD RunDog:execute

	do while .not. ::terminated
		oApp:setPointer(,::aniAct,XBPWINDOW_POINTERTYPE_ICON)
		::aniAct += 10
		if ::aniAct > 1060
			::aniAct := 1010
		endif
		sleep( 15 )
		::checkTermination()
	enddo
RETURN self

// Diese Methode prüft ob der Thread abgebrochen werden muß
// und terminiert ihn gegebenenfalls

METHOD RunDog:checkTermination
	IF ::terminated
		 ::terminated := .F.
	   oApp:setPointer( , 0, XBPWINDOW_POINTERTYPE_SYSPOINTER )
		 ::quit()
	ENDIF
RETURN self
Gestartet wird der Thread im Prinzip von außen wie folgt:

Code: Alles auswählen

oRunDog := RunDog():New()
oRunDog:start()
und gestoppt:

Code: Alles auswählen

oRunDog:stop()
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
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von Jan »

Das heißt, ich muß eine eigene Klasse schreiben dafür? Denn: Meine Threads laufen alle parallel, und die Variablennamen sind alle LOCAL in den jeweils aufrufenden Funktionen.

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

Re: Anderen Thread beenden

Beitrag von Martin Altmann »

Hallo Jan,
Du kannst keinen Thread von außen aus einem anderen Thread heraus direkt beenden - nur indirekt!
Das quit muss in dem jeweiligen Thread erfolgen, der beendet werden soll. Also musst Du (analog zu meinem Beispiel oder dem 2. Beispiel in der Hilfe zu Threads) vorgehen.

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
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von Jan »

Martin, das ist mir schon klar. Mir ist aber nicht klar, wie ich da ran komme. Ich würde mir das ja gerne einfach machen mit Thread(cName):stop(). Aber das geht ja wohl nicht.

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

Re: Anderen Thread beenden

Beitrag von Martin Altmann »

Jan,
Du kannst nicht von außen den Thread stoppen. Du kannst dem Thread nur von außen signalisieren, dass er sich beenden soll.
Wie Du das machst, bleibt Dir überlassen!
Entweder rufst Du von außen eine Methode auf, die eine Membervariable setzt, die Du während Deiner Threadinternen Verarbeitung immer wieder abfragst (wie im 2. Beispiel zur Hilfe zum Thema Threads) oder ob Du von außerhalb eine PUBLIC Variable setzt, die Du während Deiner Threadinternen Verarbeitung immer wieder abfragst oder ob Du mit einer anderen Variante arbeitest (Datenbankeintrag, Farbe eines Pixels an einer bestimmten Koordinate in Deinem Fenster,....) bleibt Dir überlassen.

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
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Anderen Thread beenden

Beitrag von AUGE_OHR »

Jan hat geschrieben:Kann mir jemand sagen, wie ich einen bestimmten Thread aus einem anderen heraus beenden kann? Ich kann den mit dem Threadnamen identifizieren...
ich habe alle Thread Objecte in ein Array aufgenommen.
Wenn ich was von den will schicke ich ein PostAppEvent() an den betreffenden Thread.

Code: Alles auswählen

#define XbeE_StopThread      xbeP_User+100

PostAppEvent(XbeE_StopThread,,,myThreadObject)
und im Thread dann

Code: Alles auswählen

DO WHILE .NOT. lExit
     nEvent := AppEvent( @mp1, @mp2, @oXbp, nTimeOut)
     DO CASE
          CASE nEvent == xbe_None                            // Timeout
               EXIT
          CASE nEvent == XbeE_StopThread
               EXIT
gruss by OHR
Jimmy
Benutzeravatar
Klaus Schuster
Foren-Administrator
Foren-Administrator
Beiträge: 366
Registriert: Do, 24. Jan 2008 10:01
Wohnort: 90762 Fürth
Hat sich bedankt: 9 Mal
Danksagung erhalten: 9 Mal

Re: Anderen Thread beenden

Beitrag von Klaus Schuster »

Hallo Martin,

welches Objekt soll oApp enthalten? setAppWindow()? Ausgeführt wird der Thread, zeigt aber nichts an.
Gruß Klaus
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von Martin Altmann »

Hallo Klaus,
bei mir ist das das Hauptfenster - also das eigentliche Programm.

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.
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Anderen Thread beenden

Beitrag von georg »

Hallo, Jan -


grundsätzlich kannst Du einen Thread nur beenden, wenn er sich beenden lassen will: also muss der Thread einen Event-Loop haben, der abgefragt wird. Dazu kommt ein User-Event, das programmweit als Signal gilt "Thread beenden".

Jetzt kommen die Vorlieben der einzelnen Programmierer zum Tragen. Ich habe eine eigene Thread-Klasse abgeleitet, die ich mittels einer Include-Datei und einem

Code: Alles auswählen

#TRANSLATE Thread()            => MyThread()
auf meine Thread-Klasse mappe. Die enthält eine Liste aller aktiven Threads, sowie einen Link zum jeweiligen Fenster (kein Thread ohne eigenes Fenster). Für die Inter-Thread-Kommunikation schicke ich dann das entsprechende User-Event an das Fenster des betreffenden Threads.

@Martin: ich bin bisher nicht auf die Idee gekommen, es mit dem Thread-Objekt selbst zu versuchen :banghead: Is natürlich einfacher ...

Also: von Hause aus kann Xbase++ das nicht, aber mit den vorhandenen Hausmitteln kann man sich etwas basteln, um das Problem elegant zu lösen.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Klaus Schuster
Foren-Administrator
Foren-Administrator
Beiträge: 366
Registriert: Do, 24. Jan 2008 10:01
Wohnort: 90762 Fürth
Hat sich bedankt: 9 Mal
Danksagung erhalten: 9 Mal

Re: Anderen Thread beenden

Beitrag von Klaus Schuster »

Hallo Georg,

'kein Thread ohne Fenster' würde die Einsatzmöglichkeiten sehr einschränken. Threads können im Hintergrund E-Mails versenden, Berechnungen ausführen, Daten prüfen, usw. ohne ein eigenes Fenster zu haben. Ich neigen eher zum ungekehrten Schluss: Kein Fenster ohne eigenen Thread!
Gruß Klaus
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2823
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Anderen Thread beenden

Beitrag von georg »

Hallo, Klaus -


bitte korrekt lesen:
Jetzt kommen die Vorlieben der einzelnen Programmierer zum Tragen.
auf meine Thread-Klasse mappe. Die enthält eine Liste aller aktiven Threads, sowie einen Link zum jeweiligen Fenster (kein Thread ohne eigenes Fenster).
Diese Aussage bezieht sich auf meine Programme - dort hat das bis heute sehr gut funktioniert. Aber auch Deiner Aussage
Kein Fenster ohne eigenen Thread!
kann ich zustimmen!
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von Tom »

Der Aussage mag man zustimmen, aber als Regel ist das gefährlicher Unsinn. Modulmodale Fenster haben in eigenen Threads nichts verloren, und Modalität hat ihren Zweck. Threads sind schon geil, aber zu viel Geilheit verdirbt den Spaß. :wink:
Herzlich,
Tom
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von Herbert »

Klaus Schuster hat geschrieben: Mi, 14. Feb 2018 19:46 'kein Thread ohne Fenster' würde die Einsatzmöglichkeiten sehr einschränken. Threads können im Hintergrund E-Mails versenden, Berechnungen ausführen, Daten prüfen, usw. ohne ein eigenes Fenster zu haben.
Genau da liegt die Idee der eigenen Thread-Programmierung: Etwas im Hintergrund erledigen ohne dass der Anwender etwas davon merkt und seine Arbeit dadurch nicht betroffen ist.
https://de.wikipedia.org/wiki/Thread_(Informatik)
Klaus Schuster hat geschrieben: Mi, 14. Feb 2018 19:46Ich neigen eher zum ungekehrten Schluss: Kein Fenster ohne eigenen Thread!
Da bin ich gar nicht einverstanden.
Ein Thread läuft in sich geschlossen. Daher ist ein Thread, welcher GUI-Elemente verwendet, in der Regel nicht sinnvoll. Ein Bildaufbau u.ä. ist hier als Ausnahme zu sehen, um das Entstehen eines Fensters unabhängiger zu machen. Oder der Thread verarbeitet etwas, was nur während der Lebzeit dieses Fensters gilt. Nur weiss der Thread nicht, wann der User dieses Fenbster schliesst.
Windows selber arbeitet auch mit Threads (siehe Wiki-Link) und mit eigener Programmierung funkt ihr da hinein. Ich zweifle, ob viele Threads das Programm wirklich effektiver machen kann, im Gegenteil, wie auch Tom bemerkt:
Tom hat geschrieben: Mi, 14. Feb 2018 21:18 aber als Regel ist das gefährlicher Unsinn. Modulmodale Fenster haben in eigenen Threads nichts verloren, und Modalität hat ihren Zweck. Threads sind schon geil, aber zu viel Geilheit verdirbt den Spaß. :wink:
Modale Fenster sollten ohnehin in einem schlauen Programm nie oder nur ganz selten (Datensicherung usw.) vorkommen.Sonst müssten wir dann mal über Design sprechen.
Grüsse Herbert
Immer in Bewegung...
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von Jan »

Bei meinen Kunden lasse ich normalerweise nur Hintergrundprozesse als eigener Thread laufen. Wie die Abfrage nach neuen internen Nachrichten, die dann in einem Infofenster aufgeführt werden. Oder eine Videoüberwachung, wo jede Kamera in einem eigenen Thread läuft.

Allerdings habe ich eine eigene Software, die stark in Tabpages strukturiert ist. Und hier ist jede Tabpage ein eigener Thread, das habe ich vor ca. 10 Jahren einfach mal so umgesetzt bei der Umstellung von Clipper auf Xbase++. Ob ich das heute noch genau so stringent durchziehen würde kann ich nicht sagen. Manche der Tabpages stellen Auswertungen zusammen und geben die danach aus - da ist es gut, das die als Thread laufen, man kann währenddessen gut in anderen Tabpages weiter arbeiten. Andere geben nur aus oder dienen der Datenerfassung - ob da ein Thread sinnvoll ist mag zumindest diskussionswürdig sein.

Werden in einem Thread aber Dialoge geöffnet (modal oder wie auch immer), laufen die dann aber nicht in eigenen Threads. Ich wollte es dann doch auch nicht übertreiben.

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

Re: Anderen Thread beenden

Beitrag von Martin Altmann »

Moin Klaus,
Klaus Schuster hat geschrieben: Mi, 14. Feb 2018 18:34Ausgeführt wird der Thread, zeigt aber nichts an.
zurück zu Deiner eigentlichen Frage:
In meiner Ressourcedatei sind sechs Mauszeiger hinterlegt - diese haben die IDs 1010 - 1060 (in Zehnersprüngen). Das Programm zeigt also einen der Mauszeiger an, wartet dann einen Moment und zeigt den nächsten an. Das kannst Du Dir wie ein langsam durchlaufendes Daumenkino vorstellen.
Damit das bei Dir funktioniert, musst Du also:
::aniAct und das Intervall an Deine Gegebenheiten anpassen
einzelne Mauszeiger Deiner Ressourcedatei hinzufügen.
Hier mal meine Bildchen in passender Reihenfolge:
Hundilein_01.png
Hundilein_01.png (491 Bytes) 10893 mal betrachtet
Hundilein_02.png
Hundilein_02.png (524 Bytes) 10893 mal betrachtet
Hundilein_03.png
Hundilein_03.png (531 Bytes) 10893 mal betrachtet
Hundilein_04.png
Hundilein_04.png (525 Bytes) 10893 mal betrachtet
Hundilein_05.png
Hundilein_05.png (504 Bytes) 10893 mal betrachtet
Hundilein_06.png
Hundilein_06.png (509 Bytes) 10893 mal betrachtet
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
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von brandelh »

Da die Xbase++ GUI in einem eigenen Thread läuft, ist es schlicht nicht nötig jedem Fenster noch einen eigenen zu verpassen.
Anders sieht das für alte Clipper Anwendungen aus, die - bisher systembedingt - nicht gleichzeitig laufen konnten, nun aber alles nebeneinander können sollen.
Solche XbpCrt() oder VIO Fenster kann man mit Threads einfach trennen, jeder mit "seinen" Arbeitsbereichen und "private" Variablen.

Ich habe immer einen Thread je Anwendung (GUI) - der darf aber nicht wirklich lange blockiert werden, daher lagere ich Funktionen nach dem Debuggen (das geht ohne eigenen Thread viel einfacher) in eigene Threads aus. Gerade Schnittstellenabfragen, Druck-Routinen oder lange Auswertungen (mit eigenen Dateien) können die GUI blocken, die kommen dann in Threads, früher habe ich statt dessen oft sleep(001) genutzt.
Gruß
Hubert
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von Herbert »

Jan hat geschrieben: Do, 15. Feb 2018 8:15 Bei meinen Kunden lasse ich normalerweise nur Hintergrundprozesse als eigener Thread laufen. Wie die Abfrage nach neuen internen Nachrichten, die dann in einem Infofenster aufgeführt werden. Oder eine Videoüberwachung, wo jede Kamera in einem eigenen Thread läuft.

Allerdings habe ich eine eigene Software, die stark in Tabpages strukturiert ist. Und hier ist jede Tabpage ein eigener Thread, das habe ich vor ca. 10 Jahren einfach mal so umgesetzt bei der Umstellung von Clipper auf Xbase++. Ob ich das heute noch genau so stringent durchziehen würde kann ich nicht sagen. Manche der Tabpages stellen Auswertungen zusammen und geben die danach aus - da ist es gut, das die als Thread laufen, man kann währenddessen gut in anderen Tabpages weiter arbeiten. Andere geben nur aus oder dienen der Datenerfassung - ob da ein Thread sinnvoll ist mag zumindest diskussionswürdig sein.

Werden in einem Thread aber Dialoge geöffnet (modal oder wie auch immer), laufen die dann aber nicht in eigenen Threads. Ich wollte es dann doch auch nicht übertreiben.
Ja, genau so macht das Sinn :thumbright:
Eh, Martin, was hat das Beenden eines Threads mit deinen Hunden gemeinsam? :dog:
Grüsse Herbert
Immer in Bewegung...
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von Martin Altmann »

Viel - schau es dir an!
Der Thread wird gestartet und wechselt den Mauszeiger kontinuierlich! Irgendwann muss er damit ja mal aufhören - das wird ihm von außen signalisiert.
Schau Dir den Beitrag mal von Anfang an an - er ist schon uralt!

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
Klaus Schuster
Foren-Administrator
Foren-Administrator
Beiträge: 366
Registriert: Do, 24. Jan 2008 10:01
Wohnort: 90762 Fürth
Hat sich bedankt: 9 Mal
Danksagung erhalten: 9 Mal

Re: Anderen Thread beenden

Beitrag von Klaus Schuster »

Moin Leute,

@Herbert: Doch, doch, es macht sehr viel Sinn sogar. Sinnvoll z.B. parallel beliebig viele Kundendaten in beliebig vielen Masken bearbeiten zu können, oder schnell zwischen Kundenmaske und Tourenpflege hin und her schalten zu können. Alle Tabelle sind stets gekapselt, der Alias stets der Tabellenname, usw. Neben der Bedienerfreundlichkeit ist Datensicherheit ein großer Gewinn. Interessant sind die drei Dokument die Claton Jones vor ein Paar Jahren verfasst hat. Der Einsatz modaler Fenster sollte den Kunden zuliebe auf ein Minimum beschränkt bleiben.

@Georg: Sehe es mir nach, doch Dein Satz war so schön kräftig, dass ich ihn aufgreifen musste.

@Tom: Es ist eher eine lange gepflegte Zuneigung, denn ein stürmisch junger Antrieb... Danke, dass Du mir den Glauben zurückgegeben hast, dass Programierung doch auch Bezüge zum Leben hat.

@Martin: Einfach, Danke!
Gruß Klaus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von brandelh »

Herbert hat geschrieben: Do, 15. Feb 2018 7:45 Ein Thread läuft in sich geschlossen. Daher ist ein Thread, welcher GUI-Elemente verwendet, in der Regel nicht sinnvoll.
Oder der Thread verarbeitet etwas, was nur während der Lebzeit dieses Fensters gilt. Nur weiss der Thread nicht, wann der User dieses Fenbster schliesst.
Dass ein Thread Infos über seinen Fortschritt anzeigt, ist schon sinnvoll, ich lese z.B. große Dateien ein.
Bei vielen Millionen Datensätzen ist ein Thread schon klasse um die GUI zu entlasten. Hier mal ein Beispiel, auch wie ich das mit den gegenseitigen Infos mache:

Code: Alles auswählen

* __DateiImport wurde mit XppFD grob erstellt und dann nachgebessert
CLASS _DateiImport FROM __DateiImport
   PROTECTED:
      VAR oThread  ********************************* diese Variable enthält den Verweis im Fenster auf den Importthread, siehe CLOSE !!!
...
   EXPORTED:
      METHOD init
      METHOD create
      METHOD CLOSE
      METHOD DateiImportieren
...
ENDCLASS
*---------------------------------------------------------------------------
METHOD _DateiImport:close()
   if ! ::oThread = NIL .and. ::oThread:active ******** das Fenster möchte schließen, aber Thread ist aktiv, was machen ???
      *** in dem Beispiel erzwinge ich den Durchlauf .... man könnte das aber auch anders regeln   
      errbox("Einlesevorgang darf nicht abgebrochen werden !")
   else
      SetAppWindow( RootWindow())
      ::destroy()
   endif
return self

*---------------------------------------------------------------------------
METHOD _DateiImport:DateiImportieren()
   local cDatei
   cDatei := ::sleDateiname:getData()
   do case
      case empty(cDatei)
           errbox("Bitte Dateinamen eingeben oder mit ... ausw„hlen !")
           SetAppFocus(::sleDateiname)
      case empty(cDatei) .or. ! file( cDatei )
           errbox("Datei: "+cDatei+" existiert nicht !"+CRLF+;
                  "Bitte Dateinamen eingeben oder mit ... ausw„hlen !")
           SetAppFocus(::sleDateiname)
      otherwise

    **** alles disablen was nicht genutzt werden darf
    
           ::mleBericht:clear()
           ::pbDateiAuswahl:disable()
           ::pbImportStarten:disable()
           ::pbCancel:disable()
           ::pbBerichtDrucken:disable()

    *** Thread anlegen, im Fenster Referenz hinterlegen und das Fenster selbst als Parameter an den Thread übergeben, 
    *** somit hat dieser Zugriff auf die GUI und VARS wenn er das braucht ...
    
           ::oThread := Thread():new()
           ::oThread:start("DoDateiImport", self , cDatei )

           // Nach Ende des Threads setzt dieser die Controls wieder aktiv !

   endcase

return self
Man könnte zum Abbruch z.B. eine iVAR ::Abbruch := .f. setzen und im Thread diese dann abfragen ... oXbp:Abbruch ????
Ich füttere die Anzeige mit Infos über die Anzahl eingelesener Datensätze ... und setze am Ende wieder enable auf die Controls.

Code: Alles auswählen

*---------------------------------------------------------------------------------------
function DoDateiImport(oXbp, cDatei) // cDatei ist Name der Textdatei
   local nDB := NIL, ... 
   ...
   
      *** Zeienweise einlesen, dafür ist der TextReader() da
      
      oTR := TextReader():new( cDatei )
      if oTR:FError() <> 0
         errbox("Fehler beim Öffnen der Datei !" + chr(13) + cDatei + chr(13) + oTR:ErrMsg())
         return 1
      endif
   
      begin sequence

      *** hier sollen die Daten rein, wichtig NEW öffnet die Datei in einem freien Selectbereich 

      USE (DatenVerzeichnis()+"xxxx") NEW
      set index to (DatenVerzeichnis()+"xxxx")
      
      *** ALIAS() ist für Menschen, PCs ziehen numerische SELECT() Werte vor, diese sind IMMER eindeutig !
      
      nDB := Select()

      ...
      nStart := seconds()
      nFehler:= 0
      nUnplausibel := 0
      cTxt := ""

      *** Infos an GUI übergeben !!!!
      
      oXbp:sleFirmenName:SetData(cFirmenName) // wird in cDatei ermittelt
      oXbp:sleFehlerAnzahl:SetData(alltrim(str(nFehler)))

      *** MLE dient als Verlaufsanzeige, zunächst immer löschen, dann cTxt einfügen
      ***     ab einer gewissen länge wird gescrollt 

      oXbp:mleBericht:clear()
      oXbp:mleBericht:insert(,cTxt)

      *** gibt der GUI Zeit das anzuzeigen, sleep(0) kostet NICHTS, gibt aber Timeslice an nächsten Thread 
      
      sleep(0) 
      
      nZei     := 0    // Textzeilenz„hler
      nAnzByte := 0    // gelesene Byte aus Quelldatei
      nAnz := 1        // hier wird mit einem angefangen, damit Anzeige besser aussieht
                       // dem Einlesen zu tun !

      cTxt += dtoc(date())+" "+time()+" - "+alltrim(str(nAnz))+" Datensätze ..."+CRLF

      oXbp:mleBericht:clear()
      oXbp:mleBericht:insert(,cTxt)


      nAnz     := 0     // Eingelesen ist noch keiner, daher auf 0 setzen
      nAnzByte := 0     // gelesene Byte

      *** immer schön über die Anzahl der neuen Datensätze informieren

      oXbp:sleSatzAnzahl:SetData(alltrim(str(nAnz)))

      do while .t.
      
         *** hier könnte man auch einen Abbruch einbauen !!!
         
         if oXbp:Abbruch
            msgbox( "von Benutzer abgebrochen" )
            BREAK
         endif   

         sleep(0)

         *** ich nehme meine Textreader Klasse
         
         cZei     := oTR:GetLine() 
         nZei++   
         nAnzByte += len(cZei)+oTR:LenCrLf() 
         cSchl    := upper(alltrim(left(cZei,10)))
         
         *** Zeile einlesen, aufteilen speichern etc. 
         *** Anzahl anzeigen

         nAnz++
         oXbp:sleSatzAnzahl:SetData(alltrim(str(nAnz)))

         if oTR:EOF() 
            exit
         endif

      enddo

      nDauer := seconds() - nStart

      beep()

      cTxt += dtoc(date())+" "+time()+" - Es wurden "+if(nFehler=0,"keine",alltrim(transform(nFehler,"999,999,999,999")))+;
              " Fehler gemeldet."+CRLF+;
              dtoc(date())+" "+time()+" - "+alltrim(transform(nAnz,"999,999,999,999"))+;
              " Datensätze wurden eingelesen (Dauer: "+alltrim(transform(nDauer/60,"9,999"))+" min)."+CRLF+;
              ...

      *** Status ausgeben 

      oXbp:mleBericht:clear()
      oXbp:mleBericht:insert(,cTxt)
      
      end sequence

   endif

   oTR:destroy()
   
   if (nDB)->(used()) 

      (nDB)->(dbcloseArea())               // sicher ist sicher

      oXbp:pbDateiAuswahl:enable()
      oXbp:pbImportStarten:enable()
      oXbp:pbCancel:enable()
      oXbp:pbBerichtDrucken:enable()
   endif

return nFehler
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Anderen Thread beenden

Beitrag von Tom »

Herbert, ich kann mir nicht vorstellen, dass Du das wirklich so gemeint hast.

Es gibt mindestens zwei grundsätzlich unterschiedliche Verwendungsgebiete für Threads:

1. Als Container für ein (komplettes) Applikationsmodul. Dadurch lässt sich das Modul beliebig oft starten, ohne sich selbst zu behindern, alle Tabellenzugriffe sind gekapselt, Fenster können nichtmodal sein. Der Thread repräsentiert quasi einen eigenen Arbeitsplatz. Darin kann man dann auch alles tun, und natürlich jede Menge GUI. Dem GUI-Thread, der mit jeder Xbase++-Applikation mitläuft, ist es übrigens völlig egal, aus welchen oder wie vielen Threads heraus er verwendet wird. Solche Threads können auf globale Variablen der Applikation, globale Einstellungen und das Applikationsobjekt zugreifen, sind aber ansonsten abgeschlossen. Man kann ihnen aber als Parameter auch Informationen über andere Threads liefern.

2. Als paralleler Prozess. Der Klassiker sind Fortschrittsanzeigen, aber man kann auch Berechnungen, Downloads und andere Vorgänge auf mehrere Threads verteilen. Viele starten mit ihren Applikationen timergesteuerte Threads, die im Hintergrund Aufgaben überwachen. Auch solche Threads können mit der Oberfläche interagieren, was zum Beispiel bei Download- oder Verarbeitungsthreads sogar geboten ist. Man schaue sich das Upsize-Tool von Alaska an. Es startet je nach Tabellengröße bis zu vier Threads, die Tabellen in Chunks aufteilen und parallel nach PostGre migrieren. Alle vier Threads informieren dieselbe Oberfläche über ihre Aktivitäten (Fortschritt). Wenn alle vier Threads beendet sind, kann sich das Modul auch beenden.
Herzlich,
Tom
Antworten