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 2 von 3     12 3      
Pilloker
(Gast)

n/a Beiträge
 
#11

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

  Alt 1. Jul 2009, 11:57
Vielen Dank an alle.

Das mit der Trennung von Anzeige und Daten ist so eine Sache, da die Anzeige ja die Daten anzeigt
Bedeutet, ich interagiere ja in dem Moment, wo ich die Daten lade, ja schon mit der Anzeige, da das VCL-Objekt ja die Daten lädt.
  Mit Zitat antworten Zitat
Benutzerbild von wicht
wicht

Registriert seit: 15. Jan 2006
Ort: Das schöne Enger nahe Bielefeld
809 Beiträge
 
Delphi XE Professional
 
#12

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

  Alt 1. Jul 2009, 12:12
Ich nochmal.

Zitat:
Bedeutet, ich interagiere ja in dem Moment, wo ich die Daten lade, ja schon mit der Anzeige, da das VCL-Objekt ja die Daten lädt.
Nein. Du interagierst (solltest du), *nachdem* du die Daten geladen hast. Nicht während dessen. Der Thread hat die Daten zu lesen/bearbeiten/was auch immer und sollte diese sich in einer Struktur merken, die einfach weiter zu verwenden ist. Zum Beispiel könnte der Thread eine Eigenschaft LoadedData haben. Und wenn der Thread das befüllt, muss er nichts synchronisieren. Sobald der Thread seine Eigensschaft LoadedData befüllt hat (Verarbeitung der Daten beendet) ruft er einmal eine Methode der Form über Synchronize auf. Die Form weißt dann ihren Controls die relevanten Sachen aus LoadedData zu. Damit ist das Laden komplett im Thread, die Anzeige der geladenen Daten komplett in der GUI. So würde das vorgehen Sinn machen (meiner Meinung nach).
http://streamwriter.org

"I make hits. Not the public. I tell the DJ’s what to play. Understand?"
  Mit Zitat antworten Zitat
Pilloker
(Gast)

n/a Beiträge
 
#13

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

  Alt 1. Jul 2009, 13:46
@wicht,

das klingt einleuchtend!
Werde das mal probieren umzusetzen.

Danke nochmal an alle!
  Mit Zitat antworten Zitat
dustin

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

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

  Alt 10. Jul 2009, 00:19
Hallo,

darf ich auch mal eine Frage bezüglich Threads stellen?

Bis dato hatte ich noch keine Threads für meine Anwendungen benötigt, bei meinem jetzigen
Projekt (Lichtsteuerung) sollten/müssen mehrere dinge selbstständig laufen.

Mein Problem ist das ich zur Laufzeit mehrere Frames erzeuge je nach Anzahl der Scheinwerfer.
Nun versuche ich in den Frames einen Thread zu integrieren damit diese Frames selbstständig ihr
Werte für die visuelle Darstellung erzeugen. Die Daten dafür sollen sie sich aus dem Hauptform
aus einem record hohlen.

Geht das überhaupt da die threads ja mit den Frames zu Laufzeit erzeugt werden.

MfG Dirk
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.464 Beiträge
 
Delphi 12 Athens
 
#15

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

  Alt 10. Jul 2009, 08:27
Funktionalität und Darstellung sollten in einem Programm sowieso getrennt sein.
Bei Threads ist das Pflicht.
Ein Beispiel wie man das in diesem Fall angehen könnte:

Definiere eine eigene Nachricht:
WM_STATUS = WM_USER + xxxx;

Aufgabe des Hauptthreads:
Vergieb für jede Aufgabe eine Nummer/ID.
Erzeuge entsprechende Threads und übergib diesen ihre Aufgaben und das Handle eines Fensters
(das über Statusänderungen informieren soll).
Erzeuge entsprechende Frames für jede zu visualisierende Aufgabe.

Aufgabe des Subthreads:
Führe deine Aufgabe aus.
Ändert sich der Status, informiere das angegebene Fenster:
PostMessage(WindowHandle, WM_STATUS, ID, 0);

Aufgabe des Hauptthreads:
Wenn eine Nachricht von über eine Statusänderung eintrifft,
finde auf Grund der ID das entsprechende Frame und rufe die Methode zur Aktualisierung der Darstellung auf.

Statt Nachrichten könnte man auch Synchronize verwenden, das bremst aber die Subthreads aus.
  Mit Zitat antworten Zitat
dustin

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

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

  Alt 11. Jul 2009, 10:53
Hallo

Danke werde mich mal mit der sache beschäftigen, habe ich noch nicht gemacht.

MfG
  Mit Zitat antworten Zitat
dustin

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

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

  Alt 14. Jul 2009, 21:27
Hallo,

mit dem ganzen Threating steige ich nicht so richtig hinter.

Jetzt habe ich gnadenlos drauf losprogrammiert ohne Rücksicht auf Verluste.

Neben dem Hauptprogramm habe ich mir einen Thread erstellt (ShowThread = class(TThread)
mit dem ich meine Ablaufsteuerung realisiert habe.
In der Ablaufsteuerung greift der Thread direkt auf einen Record (array) zu wo er sich Daten für seine Aufgabe holt und seine Ergebnisse auch wieder ablegt.
Die Daten für die VLC Komponenten mache ich über Synchronize denke das ist ok.

Auf die Felder auf die er seine Ergebnisse ablegt, schreibt auch kein anderer Thread Daten rein
also nur ein Ausgabepuffer.

Jetzt benötige ich noch einen Thread (OutputThread) der aus den Ergebnissen des Thread (ShowThread) die eigentlichen Ausgangsdaten erzeugt, muss ich da auf etwas achten (kritischer Abschnitt oder so) wenn die Daten von anderen Threads nur gelesen werden oder kann es zu Konflikten kommen?

MfG Dirk
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.464 Beiträge
 
Delphi 12 Athens
 
#18

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

  Alt 15. Jul 2009, 09:04
Sobald ein Thread in einen bestimmten Speicherbereich schreibt, ist ein "kritischer Abschnitt" erforderlich, wenn andere Threads ebenfalls lesend oder schreibend auf diesen Speicherbereich zugreifen sollen.
  Mit Zitat antworten Zitat
dustin

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

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

  Alt 22. Jul 2009, 21:01
Hallo an alle,

ich bin wahrscheinlich zu bl.....

Ich steige da nich hinter, habe zwar ein wenig gelesen aber das was ich will ist nirgens nur ansatzweise zu finden.

Habe mir mal erlaub ein Stück Quellcode reinzusetzen.

Delphi-Quellcode:
unit ShowThreadPars;

interface

uses
Windows, Messages, Classes, SysUtils, Forms, Variants, Graphics, Controls,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls, ToolWin, ParFrame;

type
  ShowThread = class(TThread)
  procedure SetData(Value:Byte);
  procedure ParsOut;
  function SetColor(Value:Byte; index:Byte): TColor;

  protected
    procedure Execute; override;
  end;

Var
   tParsindex : Byte; // Rückgabewert
   tTrackbarValue : Byte; // Rückgabewert
   tLabelValue : String; // Rückgabewert
   tShapeColor : Tcolor; // Rückgabewert

   tShapeValue : Byte;
   tDmxAdr : Byte;
   tDMXValue: Byte;
   tFrames : Integer;


   tProgRunOld : array [1..32] of Byte;
   tProgRunTemp : array [1..2,1..32] of Byte;
   tProgStepTemp : Byte = 1 ;

implementation

uses ProLightControlForm;


// -----------------------------------------------------------------------------

procedure ShowThread.Execute;
Var
 I : Byte;
begin
// stopen des thread durch hauptprogramm
  while fThreadParExit do
    begin

-------------------------------------------------------------------------------------
 'PARMAX' ist eine Variabel aus dem Hauptprogramm die sich aber jederzeit ändern kann
 auch wärend der Tread läuft
-------------------------------------------------------------------------------------
// hauptschleife für alle parser
      For i:= 1 to ParMax do
       begin
.
.
.
-------------------------------------------------------------------------------
HIER GREIFE ICH AUF VARIABLE IM HAUPTTREAD ZU UM SIE ZU LESEN BZW. ZU SCHREIBEN
-------------------------------------------------------------------------------

      tDmxAdr := ParCount[i,1]; // dmx adresse des pars hohlen
       if fStandbyActive then
         begin
            Device[tDmxAdr].DMXP := ProgRun[ProgStep,i]; // daten in ausgabe-array zurückschreiben
            tProgRunOld[i] := ProgRun[ProgStep,i]; // hilfsarray für flash funktion...
          end else begin
             Device[tDmxAdr].DMXP := tProgRunOld[i];// daten aktuell halten
          end;
.
.
.
---------------------------------------
HIER SCHREIBEN ICH DIREKT IN DEN RECORD
---------------------------------------

         if Device[tDmxAdr].ParStatus = 1 Then Device[tDmxAdr].DMXP := 255;
         SetData(tDmxAdr); // ausgabedaten berechnen
.
.
.

-----------------------------
AKTUALISIEREN DER VCL OBJEKTE
-----------------------------

         if tProgRunTemp[1,tDmxAdr] <> tProgRunTemp[2,tDmxAdr] then
// Ausgabe visualisierung
            Synchronize(ParsOut);
             tProgRunTemp[2,tDmxAdr]:=tProgRunTemp[1,tDmxAdr];
        sleep(1);
       end;
// end For next
    end;
end;
// -----------------------------------------------------------------------------
// end For next
    end;
end;
// -----------------------------------------------------------------------------

procedure ShowThread.ParsOut;
Begin
ProLightForm.Thread_Parasync(tParsindex, tTrackbarValue,tLabelValue, tShapeColor)
end;
// -----------------------------------------------------------------------------

procedure ShowThread.SetData(Value:Byte);
Var
 dmxValueStr : String;
  begin
      tShapeValue := Device[tDmxAdr].ParColorSet; // Colorindex holen
      tDMXValue := Device[tDmxAdr].ParDmxOut; // Programmwert holen
      tProgRunTemp[1,tDmxAdr]:=tDMXValue;
                                                      // nach speedfader
.
.
.
.
Es funktioniert zwar alles störungsfrei aber ich denke das es nicht richtig ist, wäre sonst zu
einfach.

Kann mir da mal jemand helfen, wie ich einen sauberen Zugriff auf Variable im Haupttread hinbekomme da die sich ständig ändernden Daten und der Tread darauf reagieren soll.


MfG Dirk
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.464 Beiträge
 
Delphi 12 Athens
 
#20

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

  Alt 23. Jul 2009, 11:08
Delphi-Quellcode:
Var
   tParsindex : Byte; // Rückgabewert
   tTrackbarValue : Byte; // Rückgabewert
   tLabelValue : String; // Rückgabewert
   tShapeColor : Tcolor; // Rückgabewert

   tShapeValue : Byte;
   tDmxAdr : Byte;
   tDMXValue: Byte;
   tFrames : Integer;


   tProgRunOld : array [1..32] of Byte;
   tProgRunTemp : array [1..2,1..32] of Byte;
   tProgStepTemp : Byte = 1 ;

implementation
Diese ganzen globalen Variablen gehn überhaupt nicht. Eine Variable sollte immer jemanden gehören.
In diesem Fall entweder einem Formular oder dem Thread und jeweils dort in den private oder protected-Abschnitt deklariert. Andere Klassen können grundsätzlich nur über property auf diese Variablen zugreifen.
-----------------------------------------------------------------------------

Delphi-Quellcode:
uses ProLightControlForm;
{...}
Synchronize(ParsOut);
{...}
procedure ShowThread.ParsOut;
Begin
ProLightForm.Thread_Parasync(tParsindex, tTrackbarValue,tLabelValue, tShapeColor)
end;
Das gehört so nicht in eine Unit, die sich um die Funktionalität kümmert (Trennung von Funktionaliät und Oberfläche).
Man kann zwei Fälle unterscheiden:
1. das Ereignis muss sofort bearbeitet und der Thread in der Zwischenzeit anhalten
2. das Ereignis kann bei nächster Gelegenheit verarbeitet werden, der Thread kann weiter arbeiten

Fall 1.:
In diesem Fall ist Synchronize() erforderlich.
Die Methode sollte aber nicht direkt, sondern über einen Methodenzeiger(oder Interface) erfolgen.
Delphi-Quellcode:
TParasyncMethode = procedure(Sender: TObject {optional weitere Parameter}) of object;

ShowThread = class(TThread)
{...}
  private
    FOnParasync: TParasyncMethode;
    procedure SetOnPararasync(AValue: TParasyncMethode);
    function GetOnPararasync: TParasyncMethode;
  public
    property OnParasync: TParasyncMethode read GetOnPararasync write SetOnPararasync;
{...}

procedure ShowThread.ParsOut;
var
  lParasync: TParasyncMethode;
Begin
  lParasync := GetOnPararasync;
  if Assigned(lParasync) then
    lParasync(Self {optional weitere Parameter});
end;
Fall 2.:
Synchronize() ist nicht erforderlich.
Der Hauptthread wird asynchron mit Hilfe von Nachrichten informiert.
Man kann ein eigenes threadsicheres Nachrichtensystem implementieren oder man nutzt das von Windows.
Delphi-Quellcode:
const
  WM_Parasync = WM_User + XXX;

ShowThread = class(TThread)
{...}
  private
    FParasyncWnd: THandle;
    procedure SetPararasyncWnd(AValue: THandle);
    function GetPararasyncWnd: THandle;
  public
    property ParasyncWnd: THandleread GetPararasyncWnr write SetPararasyncWnd;
{...}

procedure ShowThread.ParsOut;
var
  lParasyncWnd: THandle;
Begin
  lParasyncWnd := GetParasyncWnd;
  if Assigned(lParasyncWnd) then
    PostMessage(lParasyncWnd, WM_Parasync, Integer(Pointer(Self)), 0 {Optional weiterer Parameter});
end;
-----------------------------------------------------------------------------

Threadsicherer Zugriff auf interne Variabeln eines Objekts über Getter und Setter:
Delphi-Quellcode:
private
  FSection: TCriticelSection; {im Konstruktor erzeigen, im Destrucor freigeben, in der Regel wird nur eine je Objekt benötigt}
{...}

procedure ShowThread.SetPararasyncWnd(AValue: THandle);
begin
  FSection.Acquire;
  try
    FPararasyncWnd := AValue;
  finally
    FSection.Release;
  end;
end;

function ShowThread.GetPararasyncWnd: THandle;
begin
  FSection.Acquire;
  try
    Result := FPararasyncWnd;
  finally
    FSection.Release;
  end;
end;
Auf die interne Variable FPararasyncWnd darf in diesem Fall nirgends sonst zugegriffen werden,
einzige Ausnahme in einem genauso mit FSection abgesicherten Abschnitt.
Der selbe Mechanismus müsste auch in alle anderen Klassen eingebaut werden, auf dessen Property der Thread zugreifen soll.
Das würde ich aber vermeiden, neue Daten sollten immer vom Hauptthread and den Subtrhead übergeben oder von dort abgeholt werden.

Der letzte Satz sollte eigentlich deine Frage beantworten, übergib geänderte Daten an eine so absicherte Methode.
Der Thread erstellt sich eine Kopie davon und arbeitet mit dieser.

Schreibfehler wurden eingefügt, um die Aufmerksamkeit des Lesers zu erhöhen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 08:52 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