Thema: TTask Frage

Einzelnen Beitrag anzeigen

DaCoda

Registriert seit: 21. Jul 2006
Ort: Hamburg
145 Beiträge
 
Delphi 12 Athens
 
#5

AW: TTask Frage

  Alt 24. Mai 2021, 19:19
Zitat:
Du hast doch nur eine Datenquelle, oder nicht ? Da können sich doch nicht 100 Tasks gleichzeitig dranhängen ?
Genau so ist das. Ich habe nun einen anderen Ansatz genommen, so habe ich immer nur einen Task mit einer festen Verzögerung (PollTimer.Interval):

UNIT:

Code:

unit Kommunikation;

interface
uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  System.Threading,
  Vcl.Controls,
  Vcl.ExtCtrls;

type
  TIpAdresse = string[15];

  TMaschinenDaten = record
    MaschineOnline: Boolean;

  end;

  TOnDataEvent = procedure(Sender: TObject; Value: TMaschinendaten) of object;

  TMaschine = class(TObject)
  private
    FOwner: TComponent;
    FParent: TControl;
    FHostIP: TIpAdresse;
    FActive: Boolean;
    OpcTask: ITask;
    PollTimer: TTimer;
    FOnData: TOnDataEvent;
    FInterval: Cardinal;
    Maschinendaten: TMaschinendaten;

    procedure SetHostIp(Value: TIpAdresse);
    procedure SetActive(Value: Boolean);
    procedure SetInterval(Value: Cardinal);
    procedure ReadOpcData;
    procedure OnPollTimer(Sender: TObject);
    procedure OnOpcData(Sender: TObject; Value: TMaschinendaten);
  public
    constructor Create(AOwner: TComponent); virtual;
    destructor Destroy; override;

    property Parent: TControl read FParent write FParent;
    property HostIP: TIpAdresse read FHostIp write SetHostIp;
    property Active: Boolean read FActive write SetActive;
    property OnData: TOnDataEvent read FOnData write FOnData;
    property PollInterval: Cardinal read FInterval write SetInterval;
  end;

implementation

(*** TMaschine *********************************************************************************************************************************************************************)

constructor TMaschine.Create(AOwner: TComponent);
begin
  FOwner := AOwner;
  PollTimer := TTimer.Create(FOwner);
  PollTimer.Interval := FInterval;
  PollTimer.OnTimer := OnPollTimer;
  PollTimer.Enabled := False;
end;

destructor TMaschine.Destroy;
begin
  PollTimer.Enabled := False;
  TTask.WaitForAll(OpcTask);
  inherited;
end;

procedure TMaschine.SetInterval(Value: Cardinal);
begin
  FInterval := Value;
  PollTimer.Interval := Value;
end;

procedure TMaschine.OnPollTimer(Sender: TObject);
begin
  ReadOpcData;
end;

procedure TMaschine.SetHostIp(Value: TIpAdresse);
begin
  FHostIp := Value;

end;

procedure TMaschine.SetActive(Value: Boolean);
begin
  FActive := Value;
  PollTimer.Enabled := Value;
end;

procedure TMaschine.ReadOpcData;
begin
  PollTimer.Enabled := False;
  OpcTask := TTask.Create(procedure()begin

    {* HIER WERDEN DIE OPC-DATEN DANN GELESEN}

    OnOpcData(Self, Maschinendaten);
    PollTimer.Enabled := True;
  end);
  OpcTask.Start;
end;

procedure TMaschine.OnOpcData(Sender: TObject; Value: TMaschinendaten);
begin
  if Assigned(FOndata) then
   FOnData(Self, Maschinendaten);
end;


end.

AUFRUF:

Code:

unit MainForm;

interface

uses
  Kommunikation,
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs, Vcl.ExtCtrls;

type
  TfrmMain = class(TForm)
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormShow(Sender: TObject);
  private
    Maschine: TMaschine;
    MaschinenDaten: TMaschinendaten;
    procedure OnOpcData(Sender: TObject; Value: TMaschinendaten);
  public

  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.FormShow(Sender: TObject);
begin
  Maschine := TMaschine.Create(Self);
  try
    Maschine.Parent := Self.Parent;
    Maschine.OnData := OnOpcData;
    Maschine.PollInterval := 1000;
    Maschine.Active := True;
  except
    // TODO
  end;
end;

procedure TfrmMain.OnOpcData(Sender: TObject; Value: TMaschinendaten);
begin
  MaschinenDaten := Value;

end;

procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if Assigned(Maschine) then begin
    Maschine.Active := False;
    FreeAndNil(Maschine);
  end;
end;

end.
Debuggers don’t remove bugs, they only show them in slow-motion.

Geändert von DaCoda (24. Mai 2021 um 19:53 Uhr)
  Mit Zitat antworten Zitat