Einzelnen Beitrag anzeigen

Medium

Registriert seit: 23. Jan 2008
3.685 Beiträge
 
Delphi 2007 Enterprise
 
#8

AW: Label Text ändern aus einem Thread heraus

  Alt 25. Sep 2014, 20:41
Bist du sicher, dass dein Thread überhaupt bis da hin kommt? Ich sehe null Exception-Handling, dafür aber diverse Zugriffe auf Komponenten im Mainthread ohne Synchronisierung, die den Thread frühzeitig ins Nirvana schicken können. (Und auch wenn du meinst nichts auffälliges mehr zu sehen, so kann man fast garantieren, dass so lange etwas nicht geht etwas dran verkehrt ist, was andere vielleicht eher erkennen - sei es wegen größerer Erfahrung oder einfach weil man nicht wie man selbst oft im Wald steht. IMMER Source mit posten. Das ist NIE falsch. BITTE!!!)

Delphi-Quellcode:
TBackgroundThread = class(TThread)
    Text : String;
    procedure setLabelText;
    procedure Execute; override;
    constructor Create;
  end;

procedure TBackgroundThread.setLabelText;
begin
  if Text <> OverviewF.lblTaskBackground.Caption then
  begin
    Log.AddLog('Setting label to from "' + OverviewF.lblTaskBackground.Caption + '" to "' + Text + '"');
  end;
  OverviewF.lblTaskBackground.Caption := Text;
//Ja, ich hab auch alles möglich versucht update zu daten oder mit progressmessages zu arbeiten
end;

procedure TBackgroundThread.Execute;
begin
  while Application.Active do
  begin
    OverViewF.cmdProgressBackground.Reset; // <-------- Kann knallen
    if Tasks.Count > 0 then
    begin
      Tasks[0].runTask(OverViewF.cmdProgressBackground); // <-------- Kann knallen, woher kommt Tasks überhaupt!? Es ist nicht Member der Threadklasse! Also: Syncen!
      Text := Log.getLastRow; // <-------- Kann knallen (ich vermute Log ist letztlich etwas, was in ein Memo schreibt.)
      Synchronize(setLabeltext);
    end
    else
    begin
      Text := 'Nothing to do';
      Synchronize(setLabeltext);
    end;
    Sleep(10);
  end;
  Log.AddLog('Terminating Background Thread!');
end;

constructor TBackgroundThread.Create;
begin
  inherited Create;
  Log.AddLog('Creating Background Thread!');
end;
Das sind alleine schon 3 Stellen in 7 Zeilen Code vor dem Aufruf um den es geht, in dem du genau DAS tust, was man eben NICHT tut - und du sogar versuchst richtig zu machen, aber leider nur in diesem einen Fall. Gewöhne dir einfach folgendes an: immer wenn ein Thread auf Variablen zugreift, die NICHT in eben genau dieser Threadklasse bzw. ihrer Execute-Methoden liegen, synchronisieren. Wenn du damit deadlocks bekommst, ist 100%ig am Konzept etwas falsch. Wenn es zu langsam wird, hast du Racing-Conditions ohne Sync, und am Konzept stimmt etwas nicht. Behandle Threads am besten wie komplett separate Programme. (Das sind sie sogar fast, bis auf eben, dass sie im selben Prozessraum liegen wie der Hauptthread, und daher auch einfach so auf den gemeinsamen Speicher zugreifen können. Aber eben nicht unbedingt immer sollten.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (25. Sep 2014 um 20:46 Uhr)
  Mit Zitat antworten Zitat