AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!
Thema durchsuchen
Ansicht
Themen-Optionen

Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

Ein Thema von berens · begonnen am 19. Aug 2013 · letzter Beitrag vom 20. Aug 2013
Antwort Antwort
Seite 3 von 3     123   
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#21

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 19:58
Zitat:
Wenn ich Dich richtig verstehe, dürfen im Prinzip 1000 verschiedene Threads problemlos gleichzeitig tmpBestellung.ID auslesen, wenn diese irgendwie an das Objekt kommen. Was passiert, wenn dieses Objekt eine public-Variable/Objekt von frmMain ist, z.B. frmMain.AktuelleBestellung (nur als Beispiel!)?
Nur weil es ein Feld einer Form ist, heißt es nicht, dass man es nicht anfassen darf. Mit "VCL-Dinge" meinte ich bsp. Label aktualisieren, Komponenten verstecken. meineForm.verweisAufIrgendetwasAnderes kann man problemlos aus anderen Threads anfassen. Nur nicht vergessen: Wenn sich mehrere Threads für irgenetwas interessieren könnten, muss das entsprechend geschützt werden.

Zitat:
Darf ich in CriticalSection auf VCL-Objekte zugreifen? Ich muss mich da mal einlesen.
Ein kritischer Abschnitt ist keine Magie. Synchronisationshilfen wie KA oder anderes bringt nur etwas, wenn sich alle Teilnehmer auch daran halten. Und die Delphi VCL-Logik wird sich sicher nicht an deinen selbst eingeführten KA halten.

Wenn du wirklich in einem Thread direkt etwas an der VCL-Oberfläche ändern musst, dann ist dazu TThread.Synchronize(..) bzw. TThread.Queue(..) da.

Zitat:
Darf ich denn Variable, die garantiert nur vom Thread geschrieben werden (z.B. blTerminated) jederzeit ohne CriticalSelection schreiben, oder muss ich, weil ich mit frmMain im 10ms Takt "if LoadSave.blTerminated" beispielhaft überprüfe, ob der Thread fertig beendet ist unbedingt die CriticalSelection verwenden? frmMain ließt ja nur!?
Könnte man glauben, das reicht aber leider nicht. In der Praxis ist die Wahrscheinlichkeit, dass es da knallt zwar extrem gering, aber wie gesagt (es sind eigentlich wirklich nur die zwei Regeln): Sobald sich mehr als ein Thread dafür interessiert: Absichern.
Bei boolean gibt es (wahrscheinlich) keine Probleme. [...]
Auf SO gab es vor ein paar Tagen genau das Problem, dass eine Integer-Variable in einem Thread hochgezählt wurde und der Hauptthread griff nur lesend zu. Hat auf Dauer auch nicht geklappt. Ich würde nie davon ausgehen, dass da irgendetwas atomar abläuft. Auch bei Boolean nicht.

Außerdem wiederhole ich gerne noch einmal mein "Du machst es dir unnötig kompliziert": Dein TThread-Objekt hat ganz komfortabel schon Eigenschaften wie Terminated oder Finished . Die kannst du einfach lesen und brauchst dir keine Sorgen machen. Und nichts eigenes erfinden.
  Mit Zitat antworten Zitat
berens

Registriert seit: 3. Sep 2004
431 Beiträge
 
Delphi 2010 Professional
 
#22

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 20:14
Günther: Bin mir nicht sicher, aber ich glaube in Delphi 2007 gibt es TThread.Finished nicht.

TThread.Terminate setzt ja nur die Boolean-Variable des Threads auf Terminated, ich kann ja (ohne das Finished von oben) nicht so einfach ohne eigene Variable feststelle, ob .Execute nun ordnungsgemäß beendet wurde?

Klar, es gibt Event.WaitFor. Damit habe ich noch nie gearbeitet, und es scheint doch unverhältnismäßig komplizierter zu sein, als eine einfache Booleanvariable im Thread.

Zumindest das Beispiel aus der OH ist nicht wirklich selbsterklärend:
Delphi-Quellcode:
Event1.ResetEvent(); { Ereignis vor der Ausführung der Threads zurücksetzen }
for i := 1 to Counter do
TaskThread.Create(False); { Aufgaben-Threads erzeugen und ausführen }
if Event1.WaitFor(20000) <> wrSignaled then
raise Exception;
{ nun den Haupt-Threads fortsetzen Alle Aufgaben-Threads sind beendet }
Woher weiß z.B. das Event, dass es auf meinen Thread warten soll? Hier in dem Beispiel werden mehrere Threads erzeugt. Woher weiß das Event, dass alle fertig sind? Wird wrSignaled immer von Thread nach der Beendigung von Terminate gesetzt? Fragen über Fragen.

Weiterhin Danke an Alle!
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#23

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 20:30
Falls es die Finished -Property noch nicht gibt, dann doch wenigstens das onTerminate -Ereignis? Das wird ausgeführt, wenn der Thread seine Execute-Methode verlassen hat. Als Bonus wird die Methode bereits im Kontext des Hauptthreads ausgeführt, du kannst also schon gefahrlos an VCL-Komponenten herumwerkeln.

Darin kannst du ja dann auch einfach eine meineForm.derThreadIstFertig := True setzen.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.009 Beiträge
 
Delphi 12 Athens
 
#24

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 21:21
Uwe: Erklär mir doch bitte noch in 1-2 Sätzen, wie ich den Thread ohne Aufruf eines Synchronize abbrechen kann.
Innherhalb des Execute fragst du regelmäßig Terminated ab. Wenn du von außerhalb den Thread beenden willst, rufst du MyThread.Terminate (oder wie die Variable auch heißt, in der du dir Thread-Instanz ablegst) auf. Das ist der empfohlene Weg.

Willst du im Hauptthread auf das Ende von MyThread warten, hilft MyThread.WaitFor (gegebenfalls mit einem Timeout).
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
662 Beiträge
 
#25

AW: Exception ohne wirklichen Auslöser treibt mich in den Wahnsinn!

  Alt 20. Aug 2013, 21:26
Zumindest das Beispiel aus der OH ist nicht wirklich selbsterklärend:
Delphi-Quellcode:
Event1.ResetEvent(); { Ereignis vor der Ausführung der Threads zurücksetzen }
for i := 1 to Counter do
TaskThread.Create(False); { Aufgaben-Threads erzeugen und ausführen }
if Event1.WaitFor(20000) <> wrSignaled then
raise Exception;
{ nun den Haupt-Threads fortsetzen Alle Aufgaben-Threads sind beendet }
Hier in dem Beispiel werden mehrere Threads erzeugt. Woher weiß das Event, dass alle fertig sind?
Der Letzte macht das Licht aus
Das steht weiter oben im Beispiel der OH:

Delphi-Quellcode:
 procedure TDataModule.TaskTerminateThread(Sender: TObject);
 begin
   ...
   CounterGuard.Acquire; { Zähler mit einer Sperre belegen }
   Dec(Counter); { Wert der globalen Zählervariable verringern }
   if Counter = 0 then
     Event1.SetEvent; { Signalisieren, ob es der letzte Thread ist }
   Counter.Release; {Sperre vom Zähler entfernen}
   ...
 end;
Der Counter wird im OnTerminate eines jeden Threads heruntergezählt (mit critical section versteht sich!). Wenn 0 erreicht ist, weiß der Thread, dass er der letzte ist und macht das Lich aus (SetEvent).
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz