Einzelnen Beitrag anzeigen

HolgerX

Registriert seit: 10. Apr 2006
Ort: Leverkusen
961 Beiträge
 
Delphi 6 Professional
 
#11

AW: Thread CriticalSection bzw TMultiReadExclusiveWriteSynchronizer pro Property

  Alt 17. Nov 2019, 06:20
Hmm..


Delphi-Quellcode:

procedure TthrTest.Execute;
//******************************************************************************************************************************************
begin
  inherited;

  while not Terminated do
  begin
    FSection.Acquire; // Zugriff auf FListe schützen
    try
      if FListe.Count > 0 then
      begin
        Wert := FListe[0]; // ---->> Zugriff auf die Property 'Wert' und somit auf den Setter 'SetWert'
        FListe.Delete(0);
      end;
    finally
      FSection.Release; // Zugriff auf FListe wieder freigeben
    end;
    TThread.Sleep(300);
  end;
end;

procedure TthrTest.SetWert(const Value: String);
//******************************************************************************************************************************************
var
  bChanged: Boolean;

begin
  FSection.Acquire; // Zugriff auf FWert schützen
  try
    bChanged := (FWert <> Value);
    if bChanged then
      FWert := Value;
  finally
    FSection.Release; // Zugriff auf FWert wieder freigeben
  end;

  // Nicht innerhalb der CriticalSection da Main sonst blockieren könnte
  if bChanged then
    Synchronize(SyncEventWert);
end;

Der DeadLock kommt hier deshalb, weil Du innerhalb des Locks im Execute auf den Setter von Wert zugreifst, welcher selber wieder ein Lock machen will...

Dein Synchronize sollte auch nicht im Setter, sondern im Execute gemacht werden..

Delphi-Quellcode:

procedure TthrTest.Execute;
var
  tmpDataToSend : String;
begin
  inherited;

  FWert := '';

  while not Terminated do
  begin
    FSection.Acquire; // Zugriff auf FListe schützen
    try
      if FListe.Count > 0 then
      begin
        FWert := FListe[0];
        FListe.Delete(0);
      end;
    finally
      FSection.Release; // Zugriff auf FListe wieder freigeben
    end;


    // Nicht innerhalb der CriticalSection da Main sonst blockieren könnte
    if FWert <> 'then begin
      Synchronize(SyncEventWert);
      FWert := '';
    end;

    TThread.Sleep(1);
  end;
end;

Deine Property Wert mit seinem Setter ist somit Überflüssig,ja sogar falsch, da deine Liste über 'SendToListe' gefüllt wird und auf FWert nur innerhalb von Execute zugegriffen werden sollte, da dieser nur für Synchronize benötigt wird.

Für den Sleep genügt auch ein Wert von einer MS...
(Ja ich Verwende Delphi 6 Pro und will NICHT wechseln!)
  Mit Zitat antworten Zitat