Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TThread und TObjectList (https://www.delphipraxis.net/108282-tthread-und-tobjectlist.html)

borncrush 10. Feb 2008 22:18


TThread und TObjectList
 
Hallo,

ich habe ein Problem, welches auch nach langer Recherche im Internet nicht geklärt werden konnte, dass mich zu schaffen macht. :roteyes:

Ich habe folgenden Thread (komplette Unit):
Delphi-Quellcode:
unit uTCalendarThread;

interface

uses
  Classes,Contnrs,StrUtils;

type
  TCDate=class(TObject)
  public
    sCaption:String;
    sStartTime:TDateTime;
    sEndTime:TDateTime;
  end;

  TCalendarThread = class(TThread)
  private

  protected
    procedure Execute; override;
  public
    CDateList:TObjectList;
    constructor Create;
    destructor Destroy;
  end;

implementation

uses SysUtils;

{ TCalendarThread }

constructor TCalendarThread.Create;
begin
  self.CDateList:=TObjectList.Create; //### #Problemstelle# ###
  inherited Create(False);
end;

destructor TCalendarThread.Destroy;
begin
  FreeAndNil(Self.CDateList);
end;

procedure TCalendarThread.Execute;
var s:TCDate;
begin
  while not Terminated do begin
    s:=TCDate.Create; //testobjekt hinzufügen
    CDateList.Clear;
    CDateList.Add(s);
  end;
end;


end.
Beim Erstellen und Starten des Thread (TCalendarThread) erhalte ich eine "Access Violation"-Meldung, solange es ein Programm mit MDI-Form ist.

Aufruf innerhalb der MDI-Form:
Delphi-Quellcode:
var TThTest:TCalendarThread;

[...]

procedure TfrmMain.FormCreate(Sender: TObject);
[...]
   TThTest:=TCalendarThread.Create(false);//Instanz erzeugen und Thread starten
[...]
Sobald ich ein Delphi-Projekt ohne MDI-Fenster erstelle/benutze, funktioniert es tadellos.
Diesen Unterschied konnte ich sicher feststellen, jedoch verstehe ich den Hintergrund nicht bzw. kann keine Lösung entwickeln. Wobei mir das Zweite wichtiger ist. :cyclops:

Ich hoffe, dass jemand mir weiterhelfen kann. :)

Thorben_Ko 10. Feb 2008 22:36

Re: TThread und TObjectList
 
SOllte an sich einfach zu beheben sein:

Delphi-Quellcode:
constructor TCalendarThread.Create;
begin
  self.CDateList:=TObjectList.Create; //### #Problemstelle# ### 
  inherited Create(False);
end;
Ich vermute mal das es daran liegt das du einer Variblen einen Wert zuweisst., welche aber noch keinen Speicher im Arbeitsspeicher reserviert bekommen hat

Delphi-Quellcode:
constructor TCalendarThread.Create;
begin  
   inherited Create(False); // erst Create, bevor du was zuweisst
  self.CDateList:=TObjectList.Create; //### #Problemstelle# ### 

end;
Vll hillft das schon

Gruss Thorben

borncrush 11. Feb 2008 07:02

Re: TThread und TObjectList
 
Guten Morgen,
danke erstmal für die Antwort.

Nochmals möchte anmerken, dass die Thread-Unit problemlos arbeitet, sobald keine MDI-Form im Delphi-Projekt vorhanden ist bzw das Hauptfenster darstellt.

Trotz alledem habe ich deinen Vorschlag ausprobiert und leider erhalte ich immernoch eine "Access Violation"-Meldung.

Da ich im Internet auch einfach nichts finden konnte, hoffe ich mal nicht, dass das Problem
unlösbar ist.
:dp: :)

Gruß

alzaimar 11. Feb 2008 07:13

Re: TThread und TObjectList
 
Du musst den Thread im 'suspended' Modus starten, sonst springt er nach dem Create u.U. gleich in die Execute-Methode.

Delphi-Quellcode:
Constructor TMyThread.Create;
Begin
  Inherited Create (True);           // stay asleep
  fLocalStuff := TLocalStuff.Create; // create local stuff
  Resume;                            // go!
End;
Dein Problem liegt vermutlich woanders, denn mit der Threadgeschichte ist alles ok. Auch wenn dein Create funktioniert, würde ich es trotzdem noch so wie von mir vorgeschlagen abändern, einfach weil es schöner ist.

Es ist zwar unschön, aber Du kannst spaßeshalber deine Liste auch in der Execute-Methode instantiieren, da dieser code im Thread läuft, das CREATE aber noch nicht.

Wo genau tritt der Fehler denn auf? Im Threadkonstruktor, oder der Execute-Methode? Greifst Du von außen auf die Liste zu? Wenn ja, wie?

borncrush 11. Feb 2008 07:24

Re: TThread und TObjectList
 
Der Vorschlag klingt sehr plausibel; hatte aus diesem Grund auch mal die Problemzeile (TObjectList.Create) in die Execute-Methode gepackt, um den zu frühen Zugriff der Execute-Methode zu verhindern, welches jedoch auch keine Besserung ergab.
Mein Konstrukt sah dann so aus:
Delphi-Quellcode:
constructor TCalendarThread.Create;
begin
  inherited Create(True);
  Resume; //### #<---nun kracht es hier # ###
end;
[...]
procedure TCalendarThread.Execute;
var s:TCDate;
begin
  self.CDateList:=TObjectList.Create; //### #Problemstelle# ###
  while not Terminated do begin
    s:=TCDate.Create; //testobjekt hinzufügen
    CDateList.Clear;
    CDateList.Add(s);
  end;
end;
Wie gesagt, ohne MDI-Form keine Probleme, mit jedoch schon. :gruebel:




Nun probierte ich natürlich auch gezielt deine Methode aus,
Delphi-Quellcode:
constructor TCalendarThread.Create;
begin
  inherited Create(True);
  self.CDateList:=TObjectList.Create; //### #Problemstelle# ###
  Resume;
end;
jedoch knallt es immernoch bei der markierten Stelle.

alzaimar 11. Feb 2008 07:32

Re: TThread und TObjectList
 
Dann liegt der Fehler nicht in dem Thread-Code.


P.S.: MDI ist doch eh veraltet... ;-)

messie 11. Feb 2008 09:02

Re: TThread und TObjectList
 
Ich hab' es mal nachgebaut. Bei mir funktioniert Dein Beispiel einwandfrei, sowohl beim Aufruf vom Mainform als auch beim Aufruf vom MDI-Child. Ich habe beide Forms automatisch erstellen lassen.

Grüße, Messie

borncrush 11. Feb 2008 17:47

Re: TThread und TObjectList
 
Ich konnte ebenfalls im Internet einen Delphi-"Progger" :) finden, der ebenfalls die selben Probleme hat, eine Lösung wurde jedoch nicht gefunden.

@alzaimar
Das der Thread-Code nicht falsch war, konnte ich mir schon denken, da es ja auch ohne MDI läuft. Trotzdem danke für Hilfeversuche.
Da wir schon mal gleich dabei sind, welche Alternative kann ich denn nutzen (im Bezug auf MDI)? Sprich ein Hauptfenster, indem die "Child"-Fenster gefangen sind, um die Übersichtlichkeit zuhalten. Habe noch noch im Internet recherchiert.

@messie
Ich denke mal es wird irgendeine Komponente sein, denn das Programm ist eine Art Warenwirtschaftssystem (Auftragsbearbeitung) in klein, dadurch ist es schon sehr komplex und deshalb kann ich nicht sukzessive Code auskommentieren, um den Fehler zu finden. Trotzdem Danke!


Wäre natürlich trotzdem sehr angenehm, wenn noch jemand eine Lösungsansatz hätte :dp: .

Bis dahin, angenehme Zeit :-D

Viele Grüße

messie 11. Feb 2008 18:24

Re: TThread und TObjectList
 
Ich würde trotzdem nochmal nachschauen, ob der Speicher beim Erzeugen des Thread schon da ist.
Delphi-Quellcode:
var TThTest:TCalendarThread;
Deklarier' das mal global an einer Stelle, die wirklich sicher erzeugt wird, z.B. in der Unit uTCalendarThread oder im HauptThread/MDI-parent. Murphy's Orakel sagt, dass da irgendwo eine ganz banale Kleinigkeit bei der Speicherzuweisung klemmt. :mrgreen: .
Hast Du Deinen Fehler mal mit MadExceptions genauer untersucht?

Grüße, Messie

borncrush 11. Feb 2008 18:52

Re: TThread und TObjectList
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ja, Messie, bin ganz deiner Meinung. Ist sicherlich ganz banal das Problem, aber erstmal finden =).

Mit MadExceptions konnte ich noch keine Erfahrungen sammeln, sprich nach deinem Post war es die erste Verwendung. :pale:
Dadurch kann ich aber leider auch nichts erkennen, im Anhang mal ein Bildschirmausschnitt.

//edit:
Hab die Deklaration mal sicher abgelegt, Fehler bleibt aber der gleiche.(edit2: Fehler bleibt nicht der gleiche, s. nächster Beitrag :pale: )


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:03 Uhr.
Seite 1 von 2  1 2      

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