Einzelnen Beitrag anzeigen

Hobbycoder

Registriert seit: 22. Feb 2017
961 Beiträge
 
#1

TThread.Queue - Datenübergabe

  Alt 5. Mai 2020, 13:57
Hi, ich nutze bisher immer einfache Events in Thread um die Daten an den Hauptthread zu übergeben. Das möchte ich jetzt mal mit Queues machen.

ein Thread sieht bei mir z.B. so aus:
Delphi-Quellcode:
unit uSQLThread.SQLGetUser;

interface

uses System.Classes, System.SysUtils, System.Types, uUser, uCallings,
  ZAbstractConnection, ZConnection, ZAbstractRODataset, ZDataset, Data.DB, uDBSettings;

type
  TOnThreadFinished=procedure(Sender: TObject) of object;
  TOnUpdateUserList=procedure(Sender: TObject; UserList: TUserList) of object;

  TSQLGetUser=class(TThread)
  private
    FViewRange: TViewRange;
    FStartdate, FEnddate: TDateTime;
    FDBSettings: TDBSettings;
    FOnThreadFinished: TOnThreadFinished;
    FOnUpdateUserList: TOnUpdateUserList;
    procedure DoThreadFinished;
    procedure DoUpdateUserList(UserList: TUserList);
  published
    property OnThreadFhinished: TOnThreadFinished read FOnThreadFinished write FOnThreadFinished;
    property OnUpdateUserList: TOnUpdateUserList read FOnUpdateUserList write FOnUpdateUserList;
  public
    constructor Create(Suspended: Boolean; DBSettings: TDBSettings; ViewRange: TViewRange; Startdate, Enddate: TDateTime);
  protected
    procedure Execute; override;
  end;

const
  DebuggingName = 'SQLGetUser';

implementation

{ TSQLTemplate }

constructor TSQLGetUser.Create(Suspended: Boolean; DBSettings: TDBSettings; ViewRange: TViewRange; Startdate, Enddate: TDateTime);
begin
  inherited Create(Suspended);
  FDBSettings:=TDBSettings.Create;
  DBSettings.AssignTo(FDBSettings);
  self.FViewRange:=ViewRange;
  self.FStartdate:=Startdate;
  self.FEnddate:=Enddate;
end;

procedure TSQLGetUser.DoThreadFinished;
begin
  if Assigned(FOnThreadFinished) then
    Synchronize(procedure
    begin
      FOnThreadFinished(Self);
    end);
end;

procedure TSQLGetUser.DoUpdateUserList(UserList: TUserList);
begin
  if Assigned(FOnUpdateUserList) then
    Synchronize(procedure
    begin
      FOnUpdateUserList(Self, UserList);
    end);
end;

procedure TSQLGetUser.Execute;
var
  FConnection: TZConnection;
  FUserList: TUserList;
begin
  self.NameThreadForDebugging(DebuggingName);
  Self.FreeOnTerminate:=True;
  FConnection:=TZConnection.Create(nil);
  FUserList:=TUSerList.Create(True);
  try
    FConnection.HostName:=FDBSettings.Hostname;
    FConnection.Port:=FDBSettings.Port;
    FConnection.User:=FDBSettings.UserName;
    FConnection.Password:=FDBSettings.Password;
    FConnection.Protocol:=FDBSettings.Provider;
    FConnection.Database:=FDBSettings.Databasename;
    FConnection.LoginPrompt:=False;
    FConnection.Connect;
    if not Self.Terminated then
    begin
      FUserList.LoadFromDB(FConnection, FViewRange, FStartdate, FEnddate);
      DoUpdateUserList(FUserList);
    end;
  finally
    FUserList.Free;
    FConnection.Free;
    FDBSettings.Free;
    DoThreadFinished;
  end;
end;

end.
Er soll eine Userliste aus eine Datenbank holen, und mir an meine Hauptthread übergeben.

Der Aufruf erfolgt so:
Delphi-Quellcode:
procedure TfrmMOMain.UpdateUserList;
var
  SQLGetUser: TSQLGetUser;
begin
  SQLGetUser:=TSQLGetUser.Create(True, FDBSettings, FViewRange, FStartDate, FEndDate);
  SQLGetUser.OnUpdateUserList:=SQLUpdateUserList;
  SQLGetUser.Resume;
end;

procedure TfrmMOMain.ThreadUpdateUserlist(sender: TObject; ThreadUserlist: TUserList);
begin
  ThreadUserlist.AssignTo(UserList);
  BuildUserList;
end;
Wie verpacke ich das jetzt in eine Queue? Ich kann ja der Queue ein Methode übergeben.
Wäre dann Anstelle von DoUpdateUserList(FUserList); ein Queue(nil, frmMOMain.ThreadUpdateUserlist(FUserList)); korrekt und ich könnte dann den Event "TOnUpdateUserList" weglassen?
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat