AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit Thread in der Klasse

Ein Thema von Megamorph · begonnen am 26. Dez 2008 · letzter Beitrag vom 27. Dez 2008
Antwort Antwort
Seite 1 von 2  1 2      
Megamorph

Registriert seit: 28. Dez 2005
25 Beiträge
 
#1

Problem mit Thread in der Klasse

  Alt 26. Dez 2008, 22:54
Ich habe leider bei der Verwendung eines Threads in meiner Klasse ein Absturtzproblem, der Compiler meldet weder Warnings noch Fehler. Hier ein Codestück:

Delphi-Quellcode:
type
  TXxxxxxx = class
    private
//...
      bActive_ : Boolean;
    public
//...
      constructor Create;
      procedure WorkThread();
      property bActive : Boolean read bActive_ write bActive_ ;
  end;

implementation

constructor TXxxxxxx.Create;
var
  ThreadID : Cardinal;
begin
//...
  CreateThread(nil, 0, @TXxxxxxx.WorkThread, nil, 0, ThreadID);
end;

procedure TXxxxxxx.WorkThread;
begin
  while true do
  begin
    MessageBox(0,'1','',MB_OK);
    if bActive_ then begin end;
    MessageBox(0,'2','',MB_OK);
  end;
end;

end.
Die erste MessageBox erscheint, dann crasht das Programm. Ich gehe davon aus, dass es ein Problem ist, vom Thread aus auf class member zuzugreifen, was ich jedoch nicht ganz verstehe, da der Thread selbst eine Methode dieser Klasse ist. Ich arbeite mit Delphi7. Wenn mir hier jemand weiter helfen könnte, wäre ich euch sehr verbunden, Danke! (-;
MfG Mega
  Mit Zitat antworten Zitat
27. Dez 2008, 09:00
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
Delphi-Frage
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#3

Re: Problem mit Thread in der Klasse

  Alt 27. Dez 2008, 10:35
MessageBox und Co sind nicht threadsicher. Du kannst sie also nicht direkt in einem Thread verwenden. Das gilt auch für alle VCL-Komponenten.

Leite deine Klasse von TThread ab und verwende die 'Synchronize'-Methode.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Megamorph

Registriert seit: 28. Dez 2005
25 Beiträge
 
#4

Re: Problem mit Thread in der Klasse

  Alt 27. Dez 2008, 11:01
Ich versichere, es liegt nicht an den Messageboxen.

Delphi-Quellcode:
procedure TXxxxxxx.WorkThread;
begin
  while true do
  begin
    MessageBox(0,'1','',MB_OK);
    if bActive_ then begin end;
    MessageBox(0,'2','',MB_OK);
  end;
end;
--> Crash nachdem auf den OK-Button der 1. Messagebox gedrückt wurde

Delphi-Quellcode:
procedure TXxxxxxx.WorkThread;
begin
  while true do
  begin
    MessageBox(0,'1','',MB_OK);
  end;
end;
--> Nach bestätigen kommt immer wieder die selbe Messagebox, kein Crash

Delphi-Quellcode:
procedure TXxxxxxx.WorkThread;
begin
  while true do
  begin
    if bActive_ then begin end;
  end;
end;
--> sofortiger Crash

Hat noch jemand eine Idee?
Thx, Mega.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#5

Re: Problem mit Thread in der Klasse

  Alt 27. Dez 2008, 11:11
Bitte, wenn du meinst. ("Nicht threadsicher" <> "Führt garantiert zum Absturz")

Befolge meinen Rat:
1. Lies nochmal, wie man 'CreateThread' genau aufruft. Dort wird ein Zeiger auf eine Prozedur erwartet, Du übergibst einen Methodenzeiger. Vielleicht liegt es daran.
2. Verwende eine Ableitung der Klasse 'TThread' und erspare Dir Lowlevelfrust.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Megamorph

Registriert seit: 28. Dez 2005
25 Beiträge
 
#6

Re: Problem mit Thread in der Klasse

  Alt 27. Dez 2008, 11:37
> Bitte, wenn du meinst. ("Nicht threadsicher" <> "Führt garantiert zum Absturz")
- MessageBox alleine crasht nicht
- Klassenzugriff alleine crasht
Also liegt es zumindest in diesem Fall am Klassenzugriff. Die Messageboxes habe ich auch nur als Debuggingmittel verwendet, sie sollen im fertigen Programm nicht mehr im Thread laufen.

> 1. Lies nochmal, wie man 'CreateThread' genau aufruft. Dort wird ein Zeiger auf eine Prozedur erwartet, Du übergibst einen Methodenzeiger. Vielleicht liegt es daran.

Ich glaube hier ist der Knackpunkt, bei C++ muss man invoken damit es funktioniert, aber ich habe nicht gefunden, wie man das bei Delphi umsetzt.

> 2. Verwende eine Ableitung der Klasse 'TThread' und erspare Dir Lowlevelfrust.

Habe ich ursprünglich verwendet, aber wie soll ich in der TWorkThread.Execute auf Klassenelemente von TXxxxxxx zugreifen (vermutet nichts Falsches hinter der Klasse, ich habe sie nur unkenntlich gemacht).

Meine vorrübergehende Lösung:

Ich packe den Programmteil, der in einem Thread laufen soll, in eine ganz normale Methode. Diese Methode rufe ich dann im Hauptprogramm nach dem Create des Objekts nach Bauplan der Klasse in einem Thread auf.
Das funktioniert soweit, entspricht aber nicht ganz der Modularität/OOP.
Wenn jemand noch eine Idee hat, wie man in Delphi invoked oder das Problem andersweitig löst, vielen Dank! (:
MfG Mega.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#7

Re: Problem mit Thread in der Klasse

  Alt 27. Dez 2008, 12:26
Messageboxen sind threadsafe. ShowMessage icst nicht threadsafe, da es zur VCL gehört.

Wenn du trotzdem die API Funktion in einer Klasse verwenden willst, dann musst du aus der Threadfunktion eine Methode machen. Eine Methode einer Klasse hat immer noch einen unsichtbaren Self-Parameter, somit stimmt die Signtur nicht mit der Signatur der Threadfunktion überein. Eine Lösung habe ich hier: http://www.michael-puff.de/Artikel/CallbackMethod.shtml

Desweiteren solltest du nicht CreateThtrrad, sondern BeginThread nutzen. Da BeginThread die globale Variable IsMultithreaded auf true setzt und so den Heap threadsafe macht.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#8

Re: Problem mit Thread in der Klasse

  Alt 27. Dez 2008, 12:45
Ah, Luckie. Hups.

Siehst du, man sieht den Wald vor lauter Bäumen nicht. Du hast eine Klasse deklariert und übergibst einen Methodenzeiger. Obwohl, nee. Das ist gar kein Methodenzeiger, denn da ist ja kein Objekt instantiiert. Innerhalb der Methode greifst Du aber auf eine private Variable der Klasse zu. Ohne Objekt geht das immer in die Hose.

Also nochmal:
Delphi-Quellcode:
Type
  TMyThread = Class (TThread)
    fmyObject : TWhatever;
  protected
    Procedure Execute; Override;
  Public
    Constructor Create (aMyObject : TWhatever);
  End;


Constructor TMyThread.Create (aMyObject : TWhatever);
Begin
  Inherited Create(True); // noch nicht loslaufen;
  fMyObject := aMyObject;
  Resume; // Und ab
End;

Procuedre TMyThread.Execute;
Var
  anotherObject : TMyObject;

Begin
  anotherObject := TMyObject.Create;
  Try
    While Not Terminated Do Begin
      DoSomething (fMyObject);
      DoSomethingElse (anotherObject);
    End
  Finally
    anotherObject.Free;
  End;
End;

...
Begin
  MyObject := TMyObject.Create;
  MyThread := TMyThread.Create (MyObject);
...
  MyThread.Terminate;
  MyThread.WaitFor;
  FreeAndNil (MyThread);
Zitat von Megamorph:
... aber wie soll ich in der TWorkThread.Execute auf Klassenelemente von TXxxxxxx zugreifen (vermutet nichts Falsches hinter der Klasse, ich habe sie nur unkenntlich gemacht).
Bist Du sicher, Du weisst, was (Delphi)Klassen sind bzw. wie man damit arbeitet? Oder ist das nur die übliche Betriebsblindheit? Du musst ein Objekt instantiieren, um auf Klassenelemente zugreifen zu können (Ausnahme: statische Klassenmethoden und statische Klasseneigenschaften).
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Megamorph

Registriert seit: 28. Dez 2005
25 Beiträge
 
#9

Re: Problem mit Thread in der Klasse

  Alt 27. Dez 2008, 12:59
Hallo,

@Luckie: Danke, genau das habe ich gesucht! So funktioniert es jetzt auch. (-:
@alzaimar:
>Innerhalb der Methode greifst Du aber auf eine private Variable der Klasse zu. Ohne Objekt geht das immer in die Hose.

Ein klares "falsch"! Der Bauplan für ein Objekt ist eine Klasse. Methoden sind Proceduren/Funktionen, die Member der Klasse sind. Methoden können auf interne(private) und externe(public) Variablen (jedoch nicht properties) zugreifen! Das ganze auch ohne Objekt! Logischerweise wird der Code einer Methode einer Klasse erst dann ausgeführt, wenn ein Objekt nach dem Bauplan der Klasse erschaffen wurde und die Methode aufgerufen wird.

Delphi-Quellcode:
type
  TXxxxxxx = class
    private
//...
      bActive_ : Boolean;
    public
//...
      procedure WorkThread();
      property bActive : Boolean read bActive_ write bActive_ ;
  end;

implementation

procedure TXxxxxxx.WorkThread;
begin
  while true do
  begin
    MessageBox(0,'1','',MB_OK);
    if bActive_ then begin end;
    MessageBox(0,'2','',MB_OK);
  end;
end;

end.
Das hier funktioniert, wenn die Methode nun nicht gerade als Thread aufgerufen wird, obwohl die Methode WorkThread (nicht vom Namen irritieren lassen) die private Variable bActive_ benutzt. (-;

>Bist Du sicher, Du weisst, was (Delphi)Klassen sind bzw. wie man damit arbeitet? Oder ist das nur die übliche ouch! Betriebsblindheit?

Bitte nicht nur bei den anderen nach Fehlern suchen.
MfG Mega.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#10

Re: Problem mit Thread in der Klasse

  Alt 27. Dez 2008, 13:09
Was alzaimar da jetzt meinte, habe ich auch nicht so ganz verstanden. Jedenfalls kann man Klassenmethoden einer Klasse auch aufrufen ohne die zugehörige Klasse zu instanzieren. Dann kann man natürlich nicht auf andere Methoden oder Attribute der Klasse zugreifen, da sie ja nicht existieren, die Klasse wurde ja nicht instanziert und existiert im Speicher nicht. Eventuell meinte alzaimar das. Aber das machst du doch gar nicht, wenn ich das richtig sehe.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 10:58 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