AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Der Zugriff auf eine TSringList ist auf einmal nicht mehr möglixh
Thema durchsuchen
Ansicht
Themen-Optionen

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

Ein Thema von ByTheTime · begonnen am 20. Feb 2014 · letzter Beitrag vom 20. Feb 2014
Antwort Antwort
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
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#2

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

  Alt 20. Feb 2014, 19:45
Delphi-Quellcode:
 
          MInfo := res; // AUSGABE!!! <<<< Deswegen und...
          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; // <<<<<< ... Deswegen
Du weist erst res zu MInfo zu und danach zerstörst Du die StringListe. Das ist beides die selbe Referenz! Verwende Assign oder stell Die Logik entsprechend um.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

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

  Alt 20. Feb 2014, 19:47
Wenn nur ein Thread diese StringList nutzt, warum ist die dann global deklariert und nicht privat innerhalb dieses Threads?
Dann kannst du dir sicher sein, dass kein anderer diese benutzt.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.155 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

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

  Alt 20. Feb 2014, 19:48
In deiner Zeile MInfo := res; // AUSGABE!!! biegst du deine Referenz "Minfo" auf deine TStringList "res" um. Unter "res" und "Minfo" erreichst du jetzt ein und dieselbe TStringList. Und wenig später gibst du res frei. Dein "Minfo" zeigt jetzt auf einen Haufen Müll.

Wenn du jetzt später MInfo benutzt, knallt es.

Du musst an dieser Stelle den Inhalt von "res" in "Minfo" vollständig kopieren.


//Edit: Gott, was sind wir alle schnell
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#5

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

  Alt 20. Feb 2014, 19:56
//Edit: Gott, was sind wir alle schnell
Ja, uns ist wohl langweilig.
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
ByTheTime

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

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

  Alt 20. Feb 2014, 21:37
Klappt, super danke Hatte es sogar vorher richtig, habe es aber gestern geändert um was auszuprobieren und vergessen wieder rückgängig zu machen.

@SirRufo: Normalerweiße wird die StringList noch von einem anderen Thread verwendet, was ich aber bewusst verschwiegen habe, da der Thread im Moment nicht aktiv ist (Weil ich ihn schlicht und einfach für meine Testzwecke rausgenommen hab).
Lukas
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz