Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Auf Thread warten ohne Programm zu blockieren (https://www.delphipraxis.net/140937-auf-thread-warten-ohne-programm-zu-blockieren.html)

BAMatze 29. Sep 2009 10:50


Auf Thread warten ohne Programm zu blockieren
 
Hallo an alle und guten Tag,

noch eine Frage zu Threads: Ich möchte, dass mein Hauptprogramm an einer bestimmten Stelle auf meinen Thread und dessen Ergebnisse wartet. Hier mal die wichtigen Quellcode:
Delphi-Quellcode:
function TV_Tische.ConnectionTest(ChangedComportList:TStringList; AllComportList: TStringList): boolean;
var i: integer;
begin
  result := false;
  case (FiComport > 0) of
  true: begin
          // hier kommt später noch Quellcode der überprüft, ob der Comport, mit welchem das Gerät arbeitet abgeschalten wurde (ist der Comport noch in AllComportList enthalten)
        end;
  false: begin
            if ChangedComportList.Count > 0 then // gibt es Änderungen
              begin
                for i := 0 to ChangedComportList.Count - 1 do
                  begin
                    if strtoint(ChangedComportList[i]) > 0  then // welche Änderungen gibt es. Diese Liste wird in einem anderen Thread immer überprüft und über ein Event werden Änderungen in den Comports dem Hauptprogramm mitgeteilt. Dieses Event gibt aus bei welchen Comports Änderungen sich ergeben haben (dabei werden sich zuschlatende Comports mit positiven Zahlen entsprechend der Comportnummer in der Liste aufgenommen und abgeschaltene Comports mit negativen Zahlen)
                      begin
                        // es soll über einen bestimmten Zeitraum ein Kommando an den Controler über einen Thread geschickt werden und überprüft, ob dort eine entsprechende Resonanz auftritt.
                        FConnectionTest := TConnectionThread.create(strtoint(ChangedComportList[i]));
                        FConnectionTest.OnConnected := SetComPort; // Event welches ausgelöst wird, wenn eine Verbindung festgestellt wurde
                        FConnectionTest.OnTimeOut := SetTimeOut; // Event, welches ausgelöst wird, wenn die Testzeit überschritten wurde.
                        // Hier muss ich ja irgendwie warten und hier auf bezieht sich die Frage
                      end;
                  end;

              end;
          end;
  end;
end;
// Hier noch der entsprechende Thread
Type TConnectionThread = class(TThread)
  private
    FFensterHandle: HWND;
    FiComport:integer;
    FOnConnected: TOnConnected;
    FOnTimeOut: TOnTimeOut;
    // Interaktionsfunktion mit Oberfläche
  protected
    // Ausführung
    procedure Execute; override;
    // EventHandling
    procedure DoConnected;
    procedure DoTimeOut;
  public
    // Initialisierung und Terminierung
    constructor create(iComportNumber: integer); reintroduce;
    destructor destroy; override;
    // Events
    property OnConnected: TOnConnected read FOnConnected write FOnConnected;
    property OnTimeOut: TOntimeOut read FOnTimeOut write FOnTimeOut;
end;

implementation
uses TischUnit, VT_Funktionen;

constructor TConnectionThread.create(iComportNumber: integer);
var i: integer;
begin
  inherited create(false);
  FiComport := iComportNumber;
end;

destructor TConnectionThread.Destroy;
begin
  inherited destroy;
end;

procedure TConnectionThread.Execute;
var bConnected: boolean;
    c, i: integer;
begin
  bConnected := false;
  c := GetTickcount;
  repeat
    for i := 1 to 2 do
      begin
        MMC_setDevice(i);
        if MST_moving = 1 then bConnected := true;
      end;
    if not bConnected then
      begin
        for i := 1 to 2 do
          begin
            MMC_setDevice(i);
            MMC_SendCommand('FE2');
          end;
      end;
  until (c > TestTime) or bConnected;
  if bConnected then doConnected;
  if c > TestTime then doTimeOut;
end;

procedure TConnectionThread.DoConnected;
begin
  if assigned(FOnConnected) then FOnconnected(Self, FiComport);
end;

procedure TConnectionThread.DoTimeOut;
begin
  if assigned(FOnTimeOut) then FOnTimeOut(Self);
end;

end.
Vieleicht hab ich nur gerade einen Knoten im Kopf, denn ich weiß schon, ich muss ja eigentlich nur auf das TimeOut-Event warten und dadurch einfach den nächsten Comport in der Liste aufrufen. Aber ich steh gerade im Wald und sehe keine Bäume, geschweige denn eine Lösung.

Hoffe jemand kann mir da einen Denkanstoß geben.
BAMatze

BAMatze 29. Sep 2009 14:31

Re: Auf Thread warten ohne Programm zu blockieren
 
Also ich hab erstmal folgendes gemacht, wobei ich mir schon selber fast sicher bin, dass dies NICHT wirklich macht, was ich möchte.

Delphi-Quellcode:
case (FiComport > 0) of
        true: begin
                //Quellcode
              end;
        false: begin
                  if ChangedComportList.Count > 0 then
                    begin
                      for i := 0 to ChangedComportList.Count - 1 do
                        begin
                          if strtoint(ChangedComportList[i]) > 0  then
                            begin
                              MMC_COM_open(strtoint(ChangedComportList[i]),Bautrate);
                              FConnectionTest := TConnectionThread.create(strtoint(ChangedComportList[i]));
                              FConnectionTest.OnConnected := SetComport;
                              FConnectionTest.OnTimeOut := TimeOut;
                              //FConnectionTest.OnConnected := Form2.TischConnection;
                              FConnectionTest.WaitFor; // <-- Hier bin ich mir nicht wirklich sicher, ob dies das Programm dazu veranlasst zu warten, bis der Thread beendet ist.
                              if FiComport > 0 then
                                begin
                                  result := true;
                                  Break;
                                end
                              else MMC_close;
                            end;
                        end;

                    end;
                end;

// Hier auch nochmal die geänderte Execute-Funktion des Threads
procedure TConnectionThread.Execute;
var bConnected: boolean;
    c1, c2, i: integer;
begin
  bConnected := false;
  c1 := GetTickcount;
  repeat
    for i := 1 to 2 do
      begin
        MMC_setDevice(i);
        if MST_moving = 1 then bConnected := true;
      end;
    if not bConnected then
      begin
        for i := 1 to 2 do
          begin
            MMC_setDevice(i);
            MMC_SendCommand('FE2');
          end;
      end;
    c2 := getTickCount;
  until (abs(c2-c1) > TestTime) or bConnected;
  if bConnected then doConnected;
  if abs(c2 - c1) > TestTime then doTimeOut;
end;
Tja vieleicht kann jemand der sich damit besser auskennt mal das anschauen und mir sagen, ob der Thread jetzt wirklich wartet. Ich selber werde versuchen dies mal zu testen.

BAMatze

Luckie 29. Sep 2009 14:36

Re: Auf Thread warten ohne Programm zu blockieren
 
Der Code wartet nun so lange bis der Thread beendet ist.

BAMatze 29. Sep 2009 14:40

Re: Auf Thread warten ohne Programm zu blockieren
 
Ah gut, hab das nämlich aus deinem Tut für nonVCL Threads und der Hilfe vermutet (eher gehofft), dass es so funzt :-D


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