Einzelnen Beitrag anzeigen

Barthiboy

Registriert seit: 4. Nov 2011
36 Beiträge
 
#8

AW: TSQLDataSet, TSQLConnection Multithread Exception

  Alt 4. Dez 2015, 11:30
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
  Mit Zitat antworten Zitat