AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Thread mit Überwachungsfunktion wird blockiert
Thema durchsuchen
Ansicht
Themen-Optionen

Thread mit Überwachungsfunktion wird blockiert

Ein Thema von BAMatze · begonnen am 1. Sep 2009 · letzter Beitrag vom 2. Sep 2009
Antwort Antwort
Seite 1 von 2  1 2      
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#1

Thread mit Überwachungsfunktion wird blockiert

  Alt 1. Sep 2009, 12:30
Hallo und guten Tag an alle,

ich hab mal wieder eine Frage bezüglich TThread. Und zwar habe ich in Bezug auf diesen Threat meine Überwachungsfunktion für das derzeitige Projekt aus dem Timer (TControlerBoard.fdigEingaenge_pruefen(Sender: TObject); = Timerfunktion) ausgelagert und in einen Thread verfrachtet. Nun ergeben sich aber einige Problem gerade beim Laden des Programmes.

Bevor ich zur Problembeschreibung komme hier mal mein Thread-Rumpf, den ich nach einer Vorlage hier aus der DP genommen hab:

Delphi-Quellcode:
unit SteuerkartenKontrollThread;

interface

uses Classes, ExtCtrls;

Type TOndigEingang = procedure(Sender: TObject; iChannel: integer) of Object;
     TOnanaEingang = procedure(Sender: TObject; iChannel, iWert: integer) of Object;

Type TControlCardControlThread = class(TThread)
  private
    Timer: TTimer;
    FOndigEingang: TOndigEingang;
    FOnanaEingang: TOnanaEingang;
  protected
    procedure Waechter(Sender: TObject);
    procedure Execute;
    procedure dodigEingang(iChannel: integer);
    procedure doanaEingang(iChannel, iWert: integer);
  public
    constructor create; reintroduce;
    destructor destroy; override;
    property OndigEingang: TOndigEingang read FOndigEingang write FOndigEingang;
    property OnanaEingang: TOnanaEingang read FOnanaEingang write FOnanaEingang;
end;

implementation
uses Steuerkarte;

constructor TControlCardControlThread.create;
begin
  inherited create(false);
  Timer := TTimer.Create(nil);
  Timer.Enabled := true;
  Timer.Interval := 50;
  Timer.OnTimer := Waechter;
  // weitere Kommandos
end;

destructor TControlCardControlThread.Destroy;
begin
  Timer.Free;
  inherited destroy;
end;

procedure TControlCardControlThread.Execute;
var iIndex: integer;
begin
  Timer := TTimer.Create(nil);
  Timer.Enabled := true;
  Timer.Interval := 50;
  Timer.OnTimer := Waechter;
end;

procedure TControlCardControlThread.Waechter(Sender: TObject);
begin
  if ReadDigitalChannel(2) then dodigEingang(2); //hier wird derzeit eins von mehreren Events initialisiert // funktioniert
end;

procedure TControlCardControlThread.dodigEingang(iChannel: Integer);
begin
  if assigned(FOndigEingang) then FOndigEingang(Self, iChannel);
end;

procedure TControlCardControlThread.doanaEingang(iChannel: Integer; iWert: Integer);
begin
  if assigned(FOnanaEingang) then FOnanaEingang(Self, iChannel, iWert);
end;

end.
Ok zuersteinmal, weiß ich sicherlich nicht, ob diese Variante des Threads wirklich sehr "gelungen" ist. Weiß aber derzeit nicht, ob es eine bessere Alternative zu dem Timer gibt, den ich für die zyklische Abfrage meines digitalen Einganges gibt (Vorschläge werden gern angenommen).
Jetzt zu dem Problem. Die digitalen Eingänge sitzen auf einem Controlerboard, welches mir den Strom für die weitere Perepherie-Geräte freischaltet (und natürlich auch wieder ausschaltet). Dies funktioniert auch sehr gut, wenn das Programm läuft. Allerdings wenn das Programm startet, reagiert er überhaupt nicht.
Woran das liegt kann ich mir in einem gewissen Rahmen auch denken. Habe ein Splashscreen, welches in einer Schleife "ein- und ausgeblendet" wird und es werden weitere Perepherie-Geräte initialisiert.
Wie kann ich jetzt auch bei der Implementierung das Programm dazu zwingen auf die Events, die in meinem Thread erzeugt werden zu reagieren. Ich weiß ich kann Application.ProcessMessages verwenden, was mir aber nur in Teilen hilft. Z.B. wenn das im Ein- und Ausblenden der Splashscreen steht, führt es zu regelmäßigem Einfrieren des Programmes, welches nur durch das rote viereckige Kästchen in Delphi beendet werden kann. Weiterhin müssten ja grundsätzlich dann in jede Procedure welche nach dem ControlerBoard ausgeführt wird diese Application.ProcessMessages aufgerufen werden, was ein erheblicher Arbeitsaufwand wäre.
Gibt es irgendwelche anderen Möglichkeiten, das Programm zum Reagieren zu zwingen?

Vielen Dank
BAMatze
2. Account Sero
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

Re: Thread mit Überwachungsfunktion wird blockiert

  Alt 1. Sep 2009, 12:36
erstmal erstellst du 2 Timer
einmal in .Create
und nochmal in .Execute


dann braucht ein Timer eine Nachrichtenschleife
und dein Thread hat keine

Delphi hat bei sich im Hauptthread eine laufen, aber da du den Timer in deinem Thread erstellst, werden die Timer-Nachrichten an diesen Thread gesendet und von dir nicht verarbeitet, also wird auch die Timer-Ereignisprozedur nicht aufgerufen.
$2B or not $2B
  Mit Zitat antworten Zitat
Andreas L.
(Gast)

n/a Beiträge
 
#3

Re: Thread mit Überwachungsfunktion wird blockiert

  Alt 1. Sep 2009, 12:41
Hi,
ein Timer im Thread macht IMHO wenig Sinn. Machs lieber mit einer While-Schleife in Execute; deines Threads. Im Ereignis dodigEingang hast du bestimmt Code deines Hauptprogramms stehen, oder? Dann musst du dieses Ereignis synchronisieren: Synchronize(dodigEingang);
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Thread mit Überwachungsfunktion wird blockiert

  Alt 1. Sep 2009, 12:42
Zitat von himitsu:
erstmal erstellst du 2 Timer
...
und nochmal in .Execute
Jupp gesehen, hatte ich gemacht, weil das Execute nicht wirklich am Anfang ausgeführt wurde und dann nur mittels copy&paste in die create übertragen (und vergessen zu löschen )

Hast du eventuell für mich eine Möglichkeit, wie ich das lösen kann (eventuell einen kurzen Beispielcode oder Link)? Wüsste so derzeit nicht direkt, wie ich das lösen könnte

Vielen Dank
BAMatze
2. Account Sero
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.771 Beiträge
 
Delphi 10.4 Sydney
 
#5

Re: Thread mit Überwachungsfunktion wird blockiert

  Alt 1. Sep 2009, 12:46
Vielleicht läßt es sich so lösen:

Delphi-Quellcode:
procedure TControlCardControlThread.Execute;
begin
  while not terminated do
    begin
      sleep(50) // Dein Interval
      waechter; // das was du alle 50ms tun willst
      // wenn waechter auf die GUI zugreift dann
      // synchronize(waechter);
    end;
end;
Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Thread mit Überwachungsfunktion wird blockiert

  Alt 1. Sep 2009, 12:54
Zitat von Andreas L.:
Hi,
ein Timer im Thread macht IMHO wenig Sinn. Machs lieber mit einer While-Schleife in Execute; deines Threads. Im Ereignis dodigEingang hast du bestimmt Code deines Hauptprogramms stehen, oder? Dann musst du dieses Ereignis synchronisieren: Synchronize(dodigEingang);
@Andreas das dodigEingang soll eigentlich nur eine Prozedure sein, die meinem Event FOndigEingang die Informationen gibt, dass etwas passiert ist. Also findet zwischen Thread und Hauptprogramm eigentlich keine direkte Komunikation oder Zugriff auf irgendwelche Komponenten statt. Ziel ist es, dass der Thread mir Events erzeugt, auf die ich in meinem Hauptprogramm reagieren kann. Werde aber den Vorschlag von dir und Klaus mal umsetzen und das ohne Timer lösen. Wie gesagt, hatte erstmal keine andere Variante gefunden.
2. Account Sero
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

Re: Thread mit Überwachungsfunktion wird blockiert

  Alt 1. Sep 2009, 12:56
Delphi-Quellcode:
constructor TControlCardControlThread.create;
begin
  inherited create(false);
  Timer := TTimer.Create(nil);
  // hier nur alles erstellen
end;

destructor TControlCardControlThread.Destroy;
begin
  Timer.Free;
  inherited destroy;
end;

procedure TControlCardControlThread.Execute;
var iIndex: integer;
begin
  // hier alles starten
  Timer.Enabled := true;
  Timer.Interval := 50;
  Timer.OnTimer := Waechter;
  // und jetzt hier noch eine Nachrichtenschleifen hin
  // zu finden z.B. in Luckies NonVLC-Tutorials
  // aber keine via Application.irgendwas, sondern direkt über die WinAPI
  // und vergiß nicht eine nette Abbruchbedingung für
  // diese "Endlos"-Schleife zu definieren
end;
aber ich würde auch keinen Timer verwenden,
sondern via Sleep arbeiten ... also in .Execute
Delphi-Quellcode:
var c: Integer;

repeat
  c := GetTickCount;
  if ReadDigitalChannel(2) then dodigEingang(2);
  ...
  c := {interval}50 - (GetTickCount - c);
  if c > 0 then Sleep(c);
until Terminated;
Sleep(50) wenn immer 50 ms Pause dazwischen sein soll
und so wie oben wird die Bearbeitungsdauer gemessen (also wenn es auch mal etwas "länger" dauern kann
und dann nur noch die Restzeit gewartet
$2B or not $2B
  Mit Zitat antworten Zitat
Blup

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

Re: Thread mit Überwachungsfunktion wird blockiert

  Alt 1. Sep 2009, 17:04
Wenn wirklich sofort auf das Ereignis reagiert werden soll, darf Synchronize nicht verwendet werden.
Sonst wartet auch der Thread auf das nächste ProcessMessage.
Deshalb muss die aufgerufene Methode wirklich vollständig threadsicher sein (auch Zugriffe auf Klasseneigene Property).

Die Methoden doanaEingang und dodigEingang und Zugriffe auf FOndigEingang und FOnanaEingang sind ebenfalls noch nicht threadsicher.
  Mit Zitat antworten Zitat
Benutzerbild von divBy0
divBy0

Registriert seit: 4. Mär 2007
Ort: Sponheim
1.021 Beiträge
 
Delphi XE2 Professional
 
#9

Re: Thread mit Überwachungsfunktion wird blockiert

  Alt 1. Sep 2009, 18:44
Fehlt da nicht ein override?

Delphi-Quellcode:
Type TControlCardControlThread = class(TThread)
  private
    Timer: TTimer;
    FOndigEingang: TOndigEingang;
    FOnanaEingang: TOnanaEingang;
  protected
    procedure Waechter(Sender: TObject);
    procedure Execute; override; // <-- HIER
    procedure dodigEingang(iChannel: integer);
    procedure doanaEingang(iChannel, iWert: integer);
  public
    constructor create; reintroduce;
    destructor destroy; override;
    property OndigEingang: TOndigEingang read FOndigEingang write FOndigEingang;
    property OnanaEingang: TOnanaEingang read FOnanaEingang write FOnanaEingang;
end;

Ist das nicht besser so, anstatt mit Timer?

Delphi-Quellcode:
procedure TControlCardControlThread.Execute;
var iIndex: integer;
begin
  while no Terminated do
  begin
    Waechter; //Waechter muss natürlich angepasst werden wegen Sender: TObject.
    Sleep(50);
  end;
end;
Marc
9 von 10 Stimmen in meinem Kopf sagen ich bin nicht verrückt, die 10. summt die Melodie von Tetris... | Wenn das die Lösung ist, dann hätte ich gerne mein Problem zurück! | engbarth.es
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#10

Re: Thread mit Überwachungsfunktion wird blockiert

  Alt 1. Sep 2009, 20:01
Also hab jetzt mal angefangen mit Luckie´s Tut für nonVCL das mit dem WinProc mir anzueignen. Einiges hab ich schon verstanden, allerdings sind noch gerade für die Umsetzung einiges an Fragen offen. Werde mir das ganz aber erstmal weiter bis in die Tiefe zu Gemüte führen. Hoffe dadurch erledigen sich noch einige der offenen Fragen.
2. Account Sero
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 02:49 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