AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Indy TCPClient Lesethread sicher beenden
Thema durchsuchen
Ansicht
Themen-Optionen

Indy TCPClient Lesethread sicher beenden

Ein Thema von A.Griffin · begonnen am 10. Nov 2017 · letzter Beitrag vom 27. Nov 2017
 
A.Griffin

Registriert seit: 17. Feb 2017
94 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Indy TCPClient Lesethread sicher beenden

  Alt 10. Nov 2017, 13:28
Hallo zusammen,

ich habe versucht den Lesethread von hier umzusetzen.

Code:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdBaseComponent, IdComponent, idsync,
  IdTCPConnection, IdTCPClient, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    MemoReceive: TMemo;
    Button1: TButton;
    Client: TIdTCPClient;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ClientConnected(Sender: TObject);
    procedure ClientDisconnected(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TReadingThread = class(TThread)
  protected
    FConn: TIdTCPConnection;
    procedure Execute; override;
    procedure DoTerminate; override;
  public
    constructor Create(AConn: TIdTCPConnection); reintroduce;
  end;

  TLog = class(TidSync)
  protected
    FMsg: String;
    procedure DoSynchronize; override;
  public
    constructor Create(const AMsg: String);
    class procedure AddMsg(const AMsg: String);
  end;

var
  Form1: TForm1;
  rt: TReadingThread = nil;

implementation

var
  oldStatusReceive: string = 'Disconnected';
  oldStatusSend: string = 'Disconnected';
  TelegramNr: string = '00';
  sendCounter: Integer = 1;
  CommissionNumber: Integer = 1;

{$R *.dfm}

constructor TReadingThread.Create(AConn: TIdTCPConnection);
begin
  TLog.AddMsg('DEBUG: TReadingThread.Create');
  FConn := AConn;
  inherited Create(False);
end;

procedure TReadingThread.Execute;
var
  cmd, tcpStringSend: string;
begin
  TLog.AddMsg('DEBUG: TReadingThread.Execute');

  while not Terminated do
  begin
    cmd := FConn.IOHandler.ReadLn(#3);
    cmd := trim(cmd);
    TLog.AddMsg('DEBUG: TReadingThread.Execute. Cmd: ' + cmd);
    TelegramNr := copy(cmd, 1, 2);
    tcpStringSend := #2 + TelegramNr + '001050QU' + #3;
    FConn.IOHandler.WriteLn(tcpStringSend);
  end;
end;

procedure TReadingThread.DoTerminate;
begin
  TLog.AddMsg('DEBUG: TReadingThread.DoTerminate');
  inherited;
end;

constructor TLog.Create(const AMsg: string);
begin
  inherited Create;
  FMsg := AMsg;
end;

procedure TLog.DoSynchronize;
begin
  Form1.MemoReceive.Lines.Add(FMsg);
end;

class procedure TLog.AddMsg(const AMsg: string);
begin
  with Create(AMsg) do
    try
      Synchronize;
    finally
      Free;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Host: string;
  Port: Integer;
begin
  Host := '192.168.100.74';
  Port := StrToInt('4100');

  Client.Host := Host;
  Client.Port := Port;

  try
    Client.Connect;
  except
    on E: Exception do
      TLog.AddMsg('Error: ' + E.Message);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  try
    Client.Disconnect;
  except
    on E: Exception do
      TLog.AddMsg('Error: ' + E.Message);
  end;
end;

procedure TForm1.ClientConnected(Sender: TObject);
begin
  TLog.AddMsg('DEBUG: TForm1.clientConnected');
  rt := TReadingThread.Create(Client);
end;

procedure TForm1.ClientDisconnected(Sender: TObject);
begin
  TLog.AddMsg('DEBUG: TForm1.clientDisconnected');
  if rt <> nil then
  begin
    rt.Terminate;
    rt.WaitFor;
    FreeAndNil(rt);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  MemoReceive.Clear;
end;

end.
Wie lässt sich die Verbindung sicher beenden? Ich habe einen Disconnect Button hinzugefügt, aber wenn ich da drauf klicke bekomme ich eine Exception (Project1.exe raised exception class EIdNotConnected with message 'Not Connected'.) Ich nehme an, dass passiert, weil der Lesethread noch läuft und dann plötzlich die Verbindung weg ist. Wenn ich die Anwendung nach dem Verbinden einfach schließe passiert das gleiche. Ich muss also erst den Lesethread beenden und dann die Verbindung kappen. Wie beende ich den Thread, wenn er gerade beim "ReadLn" hängt und vom Server da nichts kommt? Ich habe versucht das Terminate, WaitFor, FreeAndNil vom Disconnected Event vor dem Disconnect zu machen aber dann friert die Anwendung einfach ein. Hat einer eine Idee?
  Mit Zitat antworten Zitat
 


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 14:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz