Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TThread reagiert unterschiedlich schnell (https://www.delphipraxis.net/140712-tthread-reagiert-unterschiedlich-schnell.html)

BAMatze 24. Sep 2009 11:28


TThread reagiert unterschiedlich schnell
 
Hallo und guten Tag an alle,

Hab nochmal eine Frage zu TThreads. Undzwar habe ich jetzt meinen Thread für mein Programm fertig, aber aus irgendwelchen, mir nicht wirklich verständlichen Gründen, reagiert dieser nicht so wie ich mir das vorstelle sondern eher konfus und chaotisch.

erstmal hier die wichtigsten (Execute- und Update- Funktion des Threads, weil hier der sprichwörtliche Hund begraben sein muss)

Delphi-Quellcode:
procedure TControlCardControlThread.Execute;
var c, iIndex: integer;
   
begin
  repeat
  c := GetTickCount;
  Synchronize(UpdateForm3); // gemäß Tutorial alle Interaktionen mit der Oberfläche über Synchronize
  c := {interval}50 - (GetTickCount - c);
  if c > 0 then Sleep(c);
until Terminated;
end;

{////////////////////////////////////////////////////////////////////////////////////}
{/                           Interaktion mit Oberfläche                            /}
{////////////////////////////////////////////////////////////////////////////////////}


procedure TControlCardControlThread.UpdateForm3;
var i: integer;
    bGeneralDigChannelInput, bCriticalDigChannelInput: boolean;
begin
  if Board.digEingang[1] then Form3.Statusbar1.Panels[1].Text := 'oben'
  else Form3.Statusbar1.Panels[1].Text := 'unten';
  bgeneralDigChannelInput := false;
  bcriticalDigChannelInput := false;
  for i := 1 to 5 do
    begin
      case not(FabDigChannelSignals[i] xor Board.digEingang[i]) of // wenn Werte unterschiedlich sind, dann muss etwas getan werden
      false: begin
               // Tätigkeiten wenn sich etwas an einem der 5 digitalen Eingänge getan hat
               DoSingleDigChannelInput(i); // verweißt auf ein Event, das den den Eingang mit übergibt
               bGeneralDigChannelInput := true; // boolsche Variable, die später ein Event auslöst, welches angibt ob sich generell etwas geändert hat
               if i in [2..4] then bcriticalDigChannelInput := true; // boolsche Variable, die später ein Event auslöst, wenn einer der kritischen Eingänge ausgelöst wurden.
               FabDigChannelSignals[i] := Board.digEingang[i]; // angleichen des Ausgangszustandes für nächste Prüfung
             end;
      end;
      // optische Anpassung, damit man sehen kann, was intern passiert
      (Form3.findcomponent('CheckBox' + inttostr(i+8)) as TCheckBox).Checked:= fabDigChannelSignals[i];
      if i in [1..2] then (Form3.findcomponent('ProgressBar' + inttostr(i)) as TProgressBar).Position := Board.anaEingang[i]
    end;
  // löst das blinken eines roten Lichtes an der Maschine aus
  if FbBlinkRedLight then Board.RedLight := not Board.RedLight;
  // Eventbehandlung
  if bGeneralDigChannelInput then doGeneralDigChannelInput;
  if bCriticalDigChannelInput then doCriticalDigChannelInput;

  // otpische Anpassung, um zu sehen, ob der Thread läuft
  case Counter of
  0: Form3.StatusBar1.Panels[0].Text := '/';
  1: Form3.StatusBar1.Panels[0].Text := '|';
  2: Form3.StatusBar1.Panels[0].Text := '\';
  3: Form3.StatusBar1.Panels[0].Text := '-';
  end;
  Counter := Counter + 1;
  if Counter > 3 then Counter := 0;
end;
ok folgende "Phänomene sind zu beobachten: die optische Anpassung der Checkboxen erfolgt erst nach einigen Sekunden, hingegen das Blinken des roten Lichtes erfolgt sofort, wenn der digitale Eingang ausgelöst wird. Das anpassen der Checkboxen ist dabei mit unterschiedlich langen Reaktionszeiten zu vermerken.

Warum reagieren einige Elemente in dem Thread unterschiedlich schnell? Was verlangsamt dort eventuell die Reaktionszeit des Threads? Augenscheinlich läuft der Thread konstant, was an dem drehenden Balken optisch erkennbar ist.

Hoffe Ihr könnt mir helfen
BAMatze

Uwe Raabe 24. Sep 2009 12:17

Re: TThread reagiert unterschiedlich schnell
 
Bei manchen Komponenten löst das Ändern eines Properties nicht automatisch ein Neuzeichnen aus, sondern vermerkt lediglich, daß beim nächsten Mal neu gezeichnet werden muss. Du kannst ja mal versuchen, bei den fraglichen Controls ein Refresh aufzurufen, was ein sofortiges Neuzeichnen auslöst.

Eine andere Alternative wäre, die einzelnen Zustände in eigenen Feldern zwischenzuspeichern und die Controls über den Update-Event entsprechender Actions zu aktualisieren. Damit käme das Synchronize eher zurück und der Thread kann eher weiterarbeiten. Wenn du die Zugriffe auf die Felder noch threadsicher gestaltest, kannst du auch auf das Synchronize verzichten.

mkinzler 24. Sep 2009 12:18

Re: TThread reagiert unterschiedlich schnell
 
Zudem ist Windows, kein Echtzeitbetriebssystem. Auf bestimmte feste Laufzeiten kann man sich nie verlassen

BAMatze 24. Sep 2009 12:23

Re: TThread reagiert unterschiedlich schnell
 
@Uwe und @mkinzler :thumb: hab jetzt nach meinen Übergaben an die Form3 ein Refresh der Form aufgerufen und zumindest scheint es jetzt sofort zu reagieren. Muss ich sicherlich noch eine Weile beobachten, ob es eventuell doch noch Probleme gibt aber ansonsten ist jetzt alles so, wie ich mir das gedacht hab.

Hier nochmal die ergänzte Zeile im Quellcode:
Delphi-Quellcode:
if Board.digEingang[1] then Form3.Statusbar1.Panels[1].Text := 'oben'
  else Form3.Statusbar1.Panels[1].Text := 'unten';
  bgeneralDigChannelInput := false;
  bcriticalDigChannelInput := false;
  for i := 1 to 5 do
    begin
      case not(FabDigChannelSignals[i] xor Board.digEingang[i]) of
      false: begin
               DoSingleDigChannelInput(i);
               bGeneralDigChannelInput := true;
               if i in [2..4] then bcriticalDigChannelInput := true;
               FabDigChannelSignals[i] := Board.digEingang[i];
             end;
      end;
      (Form3.findcomponent('CheckBox' + inttostr(i+8)) as TCheckBox).Checked:= fabDigChannelSignals[i];
      if i in [1..2] then (Form3.findcomponent('ProgressBar' + inttostr(i)) as TProgressBar).Position := Board.anaEingang[i]
    end;

  if FbBlinkRedLight then Board.RedLight := not Board.RedLight;

  if bGeneralDigChannelInput then doGeneralDigChannelInput;
  if bCriticalDigChannelInput then doCriticalDigChannelInput;

  Form3.Refresh; // <--eingefügt


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:41 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