Einzelnen Beitrag anzeigen

ByTheTime

Registriert seit: 24. Sep 2011
Ort: Frankfurt
297 Beiträge
 
Delphi XE2 Architect
 
#1

Der Zugriff auf eine TSringList ist auf einmal nicht mehr möglixh

  Alt 20. Feb 2014, 19:40
Hallo,
Titelwahl ist mir immer etwas schwer gefallen, aber ich versuche mal mein Problem genau zu schilder

Also, ich habe einen Service. Dort ist eine TStringList (genannt "MInfo") global deklariert. Es laufen insgesamt 3 Threads (Primärer Thread + 2 sekundäre Threads). Das sage ich extra dazu, weil die erste Reaktion wahrscheinlich wäre, das ich beim Threadhandling Mist gebaut habe, allerdings wird die StringList nur innerhalb eines Threads genutzt.

Nun passiert folgendes: Eine Funktion wird ausgeführt (genannt RunCaptured) und wandelt den Inhalt einer PDF-Datei in Text um.

Delphi-Quellcode:
function TEventThread.RunCaptured(const _dirName, _exeName,
  _cmdLine: string): Boolean;
var
  Start: TStartupInfo;
  procInfo: TProcessInformation;
  tmpName: string;
  tmp: THandle;
  tmpSec: TSecurityAttributes;
  res: TStringList;
  return: Cardinal;
begin
  Result := False;
  try
    { Setze ein Temporäres File }
    { Set a temporary file }
    tmpName := 'Test.tmp';
    FillChar(tmpSec, SizeOf(tmpSec), #0);
    tmpSec.nLength := SizeOf(tmpSec);
    tmpSec.bInheritHandle := True;
    tmp := CreateFile(PChar(tmpName), GENERIC_WRITE, File_Share_Write, @tmpSec,
      Create_Always, FILE_ATTRIBUTE_NORMAL, 0);
    try
      FillChar(Start, SizeOf(Start), #0);
      Start.cb := SizeOf(Start);
      Start.hStdOutput := tmp;
      Start.dwFlags := StartF_UseStdHandles or StartF_UseShowWindow;
      Start.wShowWindow := SW_Minimize;
      { Starte das Programm }
      { Start the program }
      if CreateProcess(nil, PChar(_exeName + ' ' + _cmdLine), nil, nil, True,
        CREATE_NO_WINDOW, nil, PChar(_dirName), Start, procInfo) then
      begin
        SetPriorityClass(procInfo.hProcess, Idle_Priority_Class);
        WaitForSingleObject(procInfo.hProcess, Infinite);
        GetExitCodeProcess(procInfo.hProcess, return);
        Result := (return = 0);
        CloseHandle(procInfo.hThread);
        CloseHandle(procInfo.hProcess);
        CloseHandle(tmp);
        { Die Ausgaben hinzufügen }
        { Add the output }
        res := TStringList.Create;
        try
          res.LoadFromFile(tmpName);
          MInfo.Clear;
          MInfo := res; // AUSGABE!!!
          Log(True, 'INFORMATION: Count of res = ' + IntToStr(res.Count) + '!');
          Log(True, 'INFORMATION: Count of MInfo = ' +
            IntToStr(MInfo.Count) + '!'); // Anzahl der Zeilen in LogDatei speichern
        finally
          res.Free;
        end;
        DeleteFile(PChar(tmpName));
      end
      else
      begin
        Log(True, 'ERROR: ' + PChar(SysErrorMessage(GetLastError())));
      end;
    except
      on E: Exception do
      begin
        Log(True, Format('ERROR: [%s] "%s"', [E.Classname, E.Message]));
        CloseHandle(tmp);
        DeleteFile(PChar(tmpName));
      end;
    end;
  finally
  end;
end;
Das funktinoert auch alles wunderbar, am Ende wird mir im Log angezeigt, das MInfo 500 Zeilen hat.

Nach dem Ausführen dieser Routine wird eine weitere Routine augeführt, die folgendermassen anfängt:

Delphi-Quellcode:
procedure TEventThread.ExtractInfo(JobID: Integer);
var
  s: String;
  i, j, k, l, EventID: Integer;
begin
  LPuffer.Clear;
  LCourses.Clear;
  LCourses.CommaText := Jobs[JobID].Courses;

  Log(True, 'INFORMATION: Count of MInfo = ' + IntToStr(MInfo.Count) + '!'); // Hier kommt es zu einem Fehler!

  if ((MInfo.Text <> EmptyStr) and (LCourses.Count <> 0)) then // !!!
  begin
  {...}
In der im Code makierten zeile, kommt es zu einer EAccessViolation. Hier wollte ich nochmals die Anzahl der Zeilen von MInfo im Log speichern. Entferne ich diese Zeile kommt es in der nächsten Zeile aufgrund von "MInfo.Text" ebenfalls zu einer EAccessViolation. Ich kann mir aber nicht erklären warum! MInfo wird nur an diesen beiden Stellen verwendet.

Hoffe jemand hat eine Idee

[EDIT] Hier nochmal die Exception: "Zugriffsverletzung bei Adresse 00000000. Lesen von Adresse 00000000" Aber das hilft auch nicht viel weiter :/

Gruß,
Lukas
Lukas

Geändert von ByTheTime (20. Feb 2014 um 19:45 Uhr) Grund: Deutsche Sprache, schwere Sprache :)
  Mit Zitat antworten Zitat