AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Thread - Synchronize - 2 Forms - Verständnisproblem
Thema durchsuchen
Ansicht
Themen-Optionen

Thread - Synchronize - 2 Forms - Verständnisproblem

Offene Frage von "jfheins"
Ein Thema von Pilloker · begonnen am 1. Jul 2009 · letzter Beitrag vom 20. Apr 2020
Antwort Antwort
Seite 3 von 3     123   
dustin

Registriert seit: 1. Jun 2009
7 Beiträge
 
#21

Re: Thread - Synchronize - 2 Forms - Verständnisproblem

  Alt 23. Jul 2009, 17:03
Hallo,

vielen Dank erstmal, ich kau das erst mal durch und muss es verdauen.

Mfg Dirk
  Mit Zitat antworten Zitat
dustin

Registriert seit: 1. Jun 2009
7 Beiträge
 
#22

Re: Thread - Synchronize - 2 Forms - Verständnisproblem

  Alt 27. Jul 2009, 19:49
Hallo Blub

nochmals danke für deine Ausführung.
Ich habe da aber so meine Verständnissprobleme oder besser gesagt das so in meinem projekt umzusetzen.

Mit der Abgrenzung der Variablen und Proceduren habe ich befolgt, leuchtet ja auch ein
da sie sonst überall verfügbar sind und ich denke mal es auch konflikte mit Namensgleichheit
geben kann.

Ich habe ein wenig gegoogelt und versucht das mit den Variablen in einem Thread zu verstehen und es giebt da wiedersprüchliche Meinungen hinsichtlich des zugriffs auf Variablen ausserhalb eines Thread's.

Manche sagen jeder Zugriff ob schreiben oder lesen muss abgesichert werden ander wiederung nur das scheiben da bei lesezugriffe keine werte verändert werden und auch nur den wenn mehrere Thread in gleiche Variable schreiben.
Wie schon gesagt benutzen ich einen Record der alle informationen für die Steuerung enthält.
Die dort abgespeicherten Daten werden jeweils nur von einem thread veränder, alle ander höhlen sich zu gegebener Zeit die Daten um damit wiederum ihre Berechnungen durchzuführen und legt das Ergebnis in seine eigens für sich reservierten Variable ab damit andere Thread sie sich dort wieder holen können.

Klingt warscheinlich alles etwas kaotisch, aber ich habe hin und her überlegt wie ich eine Ablaufsteuerung hinbekomme, so das alle Module (Procsesse) selbstständig laufen ohne auf ein bestimmtes Ergebnis eine anderen Modul (Thread) zu warten, dass Hauptformular hat nur noch die Aufgabe auf Eingaben von aussen zu warten.

Das Programm läuft zwar auf meine Rechner stabil und störungsfrei ich möchte natülich konflikte weitestgehend ausschliessen.
Ich muss noch dazu sagen das ich in der Programmierung mit Delphi ein Neuling bin, bisher habe ich hauptsächlich mich mit Microcontroller beschäftigt.

Hättest du eine Idee wie ich eine Rückmeldung in einen Thread machen kann wenn ein Benutzer einen Button oder eine Trackbar betätigt (bisher habe ich das auch über Variablen gemacht, geht auch) da der Thread diese informationen verarbeiten soll. Eine message denke ich geht nicht die müssten dann ja in mengen verschickt werden solange wie die Trackbar bedient wird.

Die Sache mit der VCL Aktualiesierng per PostMessage gefällt mir zwar ser gut bekomme ich aber irgendwie nicht hin (Fensterhandle). Die Form für die Visualisierung werden zur Laufzeit erstellt je nach Bedarf und Menge. Auch zur Laufzeit kann sich das noch durch Benutzereingabe ändern.
Giebt es eigendlich auch eine möglichkeit Message zu versenden ohne Handle wo jeder diese empfängt und je nach Parameter dann die Daten für sich in anspruch nimmt.

Jetzt will ich deine Gedult mit meinen Problemen nicht überstrapazieren.

MfG Dirk

PS: Ich kann dir ja das Prog mal als lauffähige Variante zumailn damit du eine Vorstellung hast wass ich da treibe. Vieleicht erklären sich dann meine Probleme besser.
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.429 Beiträge
 
Delphi 10.4 Sydney
 
#23

Re: Thread - Synchronize - 2 Forms - Verständnisproblem

  Alt 28. Jul 2009, 10:44
Hallo Dustin,

sobald ein Thread in eine Speicherbereich schreibt und ein anderer Thread diesen liest, muss dieser Bereich geschützt werden.
Nur wenn überhaupt kein Schreibzugriff erfolgt, kann darauf verzichtet werden.
Genaue Beschreibung gibts in der Delphihilfe:
-> TCriticalSection
-> TMultiReadExclusiveWriteSynchronizer

Die Entwicklung des Anwendungsaufbaus kann ich dir nicht abnehmen, da ich die konkreten Anforderungen an dein Projekt nicht kenne.
Hier ein par Anregungen:

Ich würde jeden möglichen Prozessabschnitt als eigenständige Klasse erstellen.
Der Prozessabschnitt sollte eine Liste von Schnittstellen bereitstellen, die Eingabeparameter entgegen nehmen oder Ausgabewerte bereitstellen.
Der Abschnitt kann sich bei Bedarf einen Thread erstellen, der bestimmte Aufgaben erfüllt.
Dazu werden Eingabeparameter an threadsichere Property übergeben.

Auf Änderungen des Status/Ergebniss wird indirekt reagiert.
Der Thread schickt eine Botschaft an das Hauptformular, daß diese an den entsprechenden Prozessabschnitt übergibt.
Dieser liest den Status/Ergebniss über threadsichere Property und informiert die Ausgabeschnittstellen.
Alternativ könnte der Thread diese Aufgabe übernehmen, dafür müssen die Schnittstellen aber dann threadsicher sein.
Eine andere Möglichkeit, der Thread setzt bei Änderungen ein Property auf True, im Hauptthread werden über einen globalen Timer alle Prozessabschnitte zur Aktualisierung aufgefordert, der Thread reagiert auf das Property und setzt wieder False.

Die Erstellung und Verknüpfung der Prozessabschnitte untereinander kann im Kontext des Gesamtprogramms interaktiv mit dem Benutzer erfolgen.
Für jeden Prozessabschnitt-Klasse muss eine passendes Visualisierungsklasse existieren. Diese sollte über die Ein-und Ausgabeschnittstellen mit der Prozessklasse komunizieren und ein Steuerelement (z.B. ein Frame mit Reglern und Anzeigen) bereitstellen, steuern und Eingaben an die Prozessklasse weitergeben.
  Mit Zitat antworten Zitat
Benutzerbild von Zodi
Zodi

Registriert seit: 18. Jul 2017
Ort: Berlin
45 Beiträge
 
Delphi XE7 Ultimate
 
#24

AW: Thread - Synchronize - 2 Forms - Verständnisproblem

  Alt 19. Apr 2020, 22:06
Hab das jetzt so gelöst jetzt funktioniert es allerdings lässt sich das fenster nicht mehr verschieben wenn der Thread am zählen ist.

Delphi-Quellcode:
type
  ParseThread = class(TThread)
  private
    { Private-Deklarationen }
     Form1: TForm1;
     i:integer;
    protected
    procedure Execute; override;
    procedure DoSomething;
   public
    { Public-Deklarationen }
     constructor Create(Form1: TForm1);
end;

var
  Form1: TForm1;
  tt: ParseThread;

implementation

{$R *.dfm}

procedure ParseThread.Execute;
begin
 while not Terminated do
   begin
     Synchronize(DoSomething);
   end;
end;

procedure ParseThread.DoSomething;
begin
     inc(i);

    form1.Memo1.Lines.Add(inttostr(i));

 if i = 5000 then begin
    i:=0;
    SuspendThread(tt.Handle);
 end;
end;

constructor ParseThread.Create(Form1: TForm1);
begin
  inherited Create(False);
  Self.Form1 := Form1;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
 tt := ParseThread.Create(Self);
 tt.FreeOnTerminate := true;
end;

end.
Pascal
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#25

AW: Thread - Synchronize - 2 Forms - Verständnisproblem

  Alt 19. Apr 2020, 22:08
      Synchronize(DoSomething); Damit eliminierst du den Vorteil eines Threads und kannst ihn auch gleich weg lassen.

Hör auf den Rat den du hier im Forum bekommen hast, und arbeite ich in die Grundlagen ein.
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#26

AW: Thread - Synchronize - 2 Forms - Verständnisproblem

  Alt 20. Apr 2020, 09:40
      Synchronize(DoSomething); Damit eliminierst du den Vorteil eines Threads und kannst ihn auch gleich weg lassen.
Ich lese das immer wieder, aber es stimmt einfach nicht. Ja, Synchronize blockiert den Thread während der Aktualisierung. Es macht insofern keinen Sinn, 100% der Arbeit des Threads in einer Synchronize-Methode zu machen.

Aber es funktioniert, ist zuverlässig und einfach - und sofern der Thread 90% seiner Arbeit außerhalb des Synchronize macht, auch kein Problem!

Also ja, das ist sinnlos:
Delphi-Quellcode:
procedure ParseThread.Execute;
begin
 while not Terminated do
   begin
     Synchronize(DoSomething);
   end;
end;
Das hingegen absolut sinnvoll und schön kurz + gut lesbar:
Delphi-Quellcode:
procedure ParseThread.Execute;
begin
  while not Terminated do
  begin
    LongrunningCalculation();
    Synchronize(ShowProgress);
  end;
end;
Wobei LongrunningCalculation ruhig länger dauern darf (ist ja entkoppelt vom Hauptthread) und die Ergebnisse in Feldvariablen der Klasse schreibt. Da Synchronize blockiert, sollte Zugriff auf die Feldvariablen sicher sein. (Das ist mMn auch der Grund, weshalb es blockiert: Damit man über private Felder Daten austauschen kann)

Da inc(i) eben sehr flott ist, ist mMn das Beispiel schlecht gewählt. Eventuell ginge Primzahlen finden besser, da zeitaufwändiger ...?
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#27

AW: Thread - Synchronize - 2 Forms - Verständnisproblem

  Alt 20. Apr 2020, 13:39
Es hat mich nicht ganz losgelassen, daher hier mal ein Beispiel das Primzahlen sucht. Ja, die Berechnung ist absichtlich langsam, wobei ich nicht schätzen kann, wie langsam (Und ich hab das ohne IDe hingetippt, vll. sind da noch kleine Fehler drin)

Der Thread ist (bzgl. Abhängigkeiten) entkoppelt von der UI und steltl nur ein Event zur Verfügung. die UI kann (am Besten in einer anderen unit) dann das Event abonnieren und den Fortschritt anzeigen.

Delphi-Quellcode:
type

TPrimeInfoEvent = procedure(Sender: TPrimeFinderThread; number: Integer) of Object;

TPrimeFinderThread = class(TThread)
  private
    testNumber: Integer;
    isPrime: Boolean;
  protected
    procedure Execute; override;
    procedure ShowProgress;
    function IsNumberPrime(number: Integer);
    fProgressCallback: TPrimeInfoEvent;
  public
    { Public-Deklarationen }
    constructor Create(Form1: TForm1);
end;

implementation

constructor PrimeFinderThread.Create(callback: TPrimeInfoEvent);
begin
  inherited Create(False);
  Self.fProgressCallback = callback;
  FreeOnTerminate := True;
end;

procedure PrimeFinderThread.Execute;
begin
  testNumber = 10000;
  while not Terminated and testNumber < 1e7 do
  begin
    if IsNumberPrime(testNumber) then
      Synchronize(ShowProgress);

    testNumber := testNumber+1;
  end;
end;

procedure PrimeFinderThread.ShowProgress;
begin
  fProgressCallback(Self, testNumber);
end;

function PrimeFinderThread.IsNumberPrime(number: Integer): Boolean;
var
  i: Integer;
  divisorCount: Integer;
  remainder: Integer;
begin
  divisorCount := 0;
  for i := 1 to number do
  begin
    remainder := number;
    while remainder >= i do { remainder := number mod i }
    begin
      remainder := remainder - i;
    end
    if remainder = 0 then
      inc(divisorCount);
  end
  Result := divisorCount = 2;
end;

end.
  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 09:30 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