Einzelnen Beitrag anzeigen

Hobbycoder

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

Object wird manchmal nicht erzeugt

  Alt 11. Mai 2020, 16:06
Ich habe eine Thread, dem ich Datenbank-Verbindungsparameter übergeben will. Der Einfachheit halber habe ich diese in einer Klasse, und übergeben nur das Object (in meinem Fall DBSettings).
Nun kommt es an einem Client (von anderen erhalte ich keine Fehlermeldungen) immer zwischendurch zu einer EAccessViolation, bei einer Procedure in der Klasse.

Hier mal den entscheidenden Teil des Threads:
Delphi-Quellcode:
unit uSQLThread.SQLSaveCallActivity;

interface

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

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

  TSQLSaveCallActivity=class(TThread)
  private
    FDBSettings: TDBSettings;
    FOnThreadFinished: TOnThreadFinished;
    Ftablename: string;
    Frecordid: string;
    Fagentname: string;
    FIncoming: Integer;
    Fotherpartyphonenumber2: string;
    Flocalpartyphonenumber: string;
    FCallID: Integer;
    Fdevicename: string;
    Fotherpartyname: string;
    Fotherpartyphonenumber: string;
    Fagentguid: TGUID;
    FCallState: string;
    procedure DoThreadFinished;
  published
    property OnThreadFhinished: TOnThreadFinished read FOnThreadFinished write FOnThreadFinished;
  public
    constructor Create(Suspended: Boolean; DBSettings: TDBSettings; Agentguid: TGUID; Agentname: string;
      callid, incoming: Integer; callstate, devicename, localpartyphonenumber, otherpartyphonenumber, recordid,
      otherpartyphonenumber2, otherpartyname, tablename: string);
  protected
    procedure Execute; override;
  end;

const
  DebuggingName = 'SQLSaveCallActivity';

implementation

{ TSQLTemplate }

constructor TSQLSaveCallActivity.Create(Suspended: Boolean; DBSettings: TDBSettings; Agentguid: TGUID; Agentname: string;
      callid, incoming: Integer; callstate, devicename, localpartyphonenumber, otherpartyphonenumber, recordid,
      otherpartyphonenumber2, otherpartyname, tablename: string);
begin
  inherited Create(Suspended);
  FDBSettings:=TDBSettings.Create;
  DBSettings.AssignTo(FDBSettings); //<---Hier springt er noch rein. FDBSettings sollte erzeugt sein. DBSettings wird ja übergeben, und sollte auch vorhanden sein.
  self.Fagentguid:=Agentguid; // Zumal DBSettings vom aufrufenden Thread auch an ganz viele
  self.Fagentname:=Agentname; // andere Threads übergeben wird, und von keinem anderen eine
  self.FCallID:=callid; // Fehlermeldung kommt.
  self.FIncoming:=incoming;
  Self.FCallState:=callstate;
  self.Fdevicename:=devicename;
  self.Flocalpartyphonenumber:=localpartyphonenumber;
  self.Fotherpartyphonenumber:=otherpartyphonenumber;
  self.Frecordid:=recordid;
  self.Fotherpartyphonenumber2:=otherpartyphonenumber2;
  self.Fotherpartyname:=otherpartyname;
  self.Ftablename:=tablename;
end;
Und hier die AssignTo-Procedure der Klasse TDBSettings:
Delphi-Quellcode:
procedure TDBSettings.AssignTo(Dest: TObject);
begin
  if Dest is TDBSettings then
  begin
    (Dest as TDBSettings).Hostname:=self.FHostname; //<---Hier läufts auch noch durch
    (Dest as TDBSettings).Port:=self.FPort;
    (Dest as TDBSettings).UserName:=self.FUserName;
    (Dest as TDBSettings).Password:=self.FPassword;
    (Dest as TDBSettings).Provider:=self.FProvider;
    (Dest as TDBSettings).Databasename:=self.FDatabasename;
  end;
end;

.
.
.
procedure TDBSettings.SetHostname(const Value: string);
begin
  FHostname := Value; //<--Hier kommt dann die Exception.
end;
Auf Grund der Tatsache, dass die Exception im Setter auftritt, und ich in der AssignTo-Procedure nur für das Destination-Object über den Setter gehe, wäre es für mich logisch, dass das Destination-Object, also FDBSettings aus dem Thread nicht existiert. Der dazugehörige Constructor ist aber fehlerfrei durchgelaufen.
Und der Fehler tritt auch nicht bei jedem Thread-Aufruf auf. Der Thread soll lediglich eine einzelne Aktivität in einer DB speichern und beendet sich danach sofort. Manche Aktivitäten werden in de DB gespeichert, andere aber nicht.
Und, es tritt nur bei einem Client auf.

Irgendjemand eine Idee?
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat