Einzelnen Beitrag anzeigen

Blup

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

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

  Alt 23. Jul 2009, 10: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