Na das is doch mal eine Ansage.
Mach ich doch gleich so gut ich kann.
ich habe jetzt mit einem try-except endlich eine genauere Fehlerbeschreibung:
04.12.2015 11:19:27 Client :
Exception = Zugriffsverletzung bei Adresse 000000000BB4768C in Modul 'dbxmss.dll'. Lesen von Adresse FFFFFFFFFFFFFFFF
04.12.2015 11:20:16 Client :
Exception = Zugriffsverletzung bei Adresse 000000000BB47680 in Modul 'dbxmss.dll'. Lesen von Adresse 0000000000000082
Der Thread sieht in etwa so aus
Delphi-Quellcode:
if DataCount > 0 then begin
// Daten einlesen
SendStr := 'Worksation;' + FormatDateTime('yyyy.mm.dd hh-nn-ss', now) + ';' + IntToStr(SessionID) + ';FetchDataToTransmit##';
FIdTCPClient.IOHandler.WriteLn(SendStr, nil);
for j := 0 to Datacount - 1 do begin
if not KommEnable then begin
// Wenn der Benutzer die Kommunikation pausiert, hier warten bis es weiter geht!
FIdTCPClient.Disconnect;
Logged := false;
break;
end;
for i := 0 to 21 do begin
Count := FIdTCPClient.IOHandler.ReadLongInt(false);
RecStr := FIdTCPClient.IOHandler.ReadString(Count, nil);
Logger.LogMessage('Server : ' + RecStr);
if DataExport then begin
SLStr := SLStr + #9 + RecStr;
end;
Daten[i] := RecStr;
if i = 21 then begin
if not DataNotInDB then begin // doppelte Verneinung (;
if Produkt_Auswerten(Daten) < 0 then begin
KommEnable := false;
end
end;
end;
RemainCount := Datacount - j - 1;
// Wenn nichts abzuholen ist
if RemainCount < 0 then RemainCount := 0;
// Ack senden
SendStr := '1';
Logger.LogMessage('Client : ' + SendStr);
FIdTCPClient.IOHandler.Write(SendStr, nil);
end;
// Einen Datensatz komplett gelesen
if DataExport then begin
SLDaten.Add(SLStr);
SLStr := '';
end;
if Terminated then begin
Break;
end;
end;
Und Das updaten der Anzeige im Main wird von einem Timer getriggert und sieht dann so aus
Delphi-Quellcode:
if SQLC_Work.Connected then begin
try
SQLDS_Work.Close;
// Aktuellen Wareneingang ermitteln
SQLDS_Work.Close;
SQLDS_Work.CommandText := 'SELECT COUNT(WareneingangsNr) from WEP02.dbo.WareneingangsNr WHERE Aktiv = 1';
SQLDS_Work.Open;
if SQLDS_Work.FieldCount > 0 then begin
if SQLDS_Work.Fields[0].AsInteger > 1 then begin // Fehler weil mehrere Wareneingänge aktiv
if Assigned(Logger) then begin
Logger.LogErrorMessage('Es sind ' + IntToStr(SQLDS_Work.RecordCount) + ' Wareneingänge aktiv. Fehler bei Timer_Chart aufgetreten');
end;
Exit;
end
else if SQLDS_Work.Fields[0].AsInteger = 0 then begin // Fehler weil kein Wareneingang aktiv
Exit;
end
else if SQLDS_Work.Fields[0].AsInteger = 1 then begin
SQLDS_Work.Close;
SQLDS_Work.CommandText := 'SELECT [IdentNr], [WareneingangsNr] from WEP02.dbo.WareneingangsNr WHERE Aktiv = 1';
SQLDS_Work.Open;
if SQLDS_Work.FieldCount > 1 then begin
IdentNr := SQLDS_Work.Fields[0].AsString;
WENr := SQLDS_Work.Fields[1].AsString;
end;
end;
end;
IdentNrOrig := IdentNr;
IdentNr := StringReplace(IdentNr, '-', '', [rfReplaceAll]);
SQLDS_Work.Close;
SQLDS_Work.CommandText := 'Select COUNT(Gesamtergebnis) from WEP02.dbo.Teil_' + IdentNr + ' WHERE Gesamtergebnis = 1';
SQLDS_Work.Open;
if SQLDS_Work.FieldCount > 0 then begin
Gut := SQLDS_Work.Fields[0].AsInteger;
end;
SQLDS_Work.Close;
SQLDS_Work.CommandText := 'Select COUNT(Gesamtergebnis) from WEP02.dbo.Teil_' + IdentNr + ' WHERE Gesamtergebnis = 0';
SQLDS_Work.Open;
if SQLDS_Work.FieldCount > 0 then begin
Schlecht := SQLDS_Work.Fields[0].AsInteger;
end;
La_Wenummer.Caption.Text := WENr;
La_Teilenummer.Caption.Text := IdentNr;
SQLDS_Work.Close;
SQLDS_Work.CommandText := 'Select (Teilename) from WEP02.dbo.Teile WHERE IdentNr = ' + quotedStr(IdentNrOrig);
SQLDS_Work.Open;
if SQLDS_Work.FieldCount > 0 then begin
Teilename := SQLDS_Work.Fields[0].AsString;
Delete(Teilename, 1, 4);
if not TryStrToInt(Teilename, SelectedModell) then begin
SelectedModell := 0;
end;
end;
Offensichtlich knallt es in der dbxmss.dll.
Allerdings wundert mich das, da ich gelesen habe das es bei multithreading keine Probleme gibt,
wenn jeder Thread seine eigene Connection hat.
Die Exceptions treten meistens auf wenn auf Fields[] zugegriffen wird
Danke