Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Thread in eigene Klasse einbinden? (https://www.delphipraxis.net/156830-thread-eigene-klasse-einbinden.html)

Edlmann 16. Dez 2010 13:18

Thread in eigene Klasse einbinden?
 
Guten Nachmittag liebe DP,

ich arbeite im Moment an einem Programm zur Wegfindung (zum späteren Bau eines simplen 2D-Spiels) und benutze hierfür den
AStar-Algorithmus. Das Funktioniert soweit auch schon ganz gut, allerdings habe ich bisher die Berechnung des Pfades in einen
Thread ausgelagert, den ich jetzt in eine eigene Klasse einbinden Möchte. Ich erzeuge den Thread mit folgendem Aufruf:

Delphi-Quellcode:
var
  ThreadParams: PThreadParams;
  ThreadID: Cardinal;
begin
  New(ThreadParams);
  ThreadParams.Handle := FormHnd;
  CloseHandle(BeginThread(nil, 0, @Thread, ThreadParams, 0, ThreadID));
Nun möchte ich meinen Thread (die Funktion Thread, die Hier verwendet wird und damit die Pfadfindung) in eine eigene Klasse einbinden.
Also dass ich etwas deklarieren kann vom Typ TPathFinder, um mehrere Pfadfindungen parallel laufen zu lassen. Soweit so gut, Problem dabei:
Sobald ich die Thread Funktion in meine eigene Klasse einbinde, meckert er dass er als Funktion eine Variable übergeben haben will.

Der Aufruf sieht dann wie folgt aus:

Delphi-Quellcode:
  New(ThreadParams);
  ThreadParams.Handle := FormHnd;
  CloseHandle(BeginThread(nil, 0, @MyPather.Thread, ThreadParams, 0, ThreadID));
Warum funktioniert dies nicht? Der Header der Funktion Thread sieht wie folgt aus:
Delphi-Quellcode:
function TPathFinder.Thread(p: PThreadParams): Integer;
Danke im Vorraus, Edlmann.

Niko 16. Dez 2010 14:27

AW: Thread in eigene Klasse einbinden?
 
Hi,

das ist ein Standardproblem. Funktionszeiger und Methodenzeiger sind nicht das Gleiche, weil eine Methode noch den impliziten Self-Parameter übergeben bekommt.

Damit du eine Methode in BeginThread verwenden kannst, muss diese entweder parameterlos sein
Delphi-Quellcode:
function TPathFinder.Thread(): Integer;
und du musst an BeginThread statt ThreadParams self übergeben oder du musst eine Klassenmethode verwenden:
Delphi-Quellcode:
class function TPathFinder.Thread(p: PThreadParams): Integer; static;

Edlmann 16. Dez 2010 14:32

AW: Thread in eigene Klasse einbinden?
 
auch mit einer Klassenfuntion funktioniert es nicht, er meint immernoch dass eine Variable erforderlich sei.
Und Ohne dass ich die Funktion in die Klasse integriert habe funktioniert es auch, dann kann ich jedoch nicht mehrere Threads parallel erstellen.

Danke trotzdem.

shmia 16. Dez 2010 14:39

AW: Thread in eigene Klasse einbinden?
 
Wieso verwendest du direkt die Thread-Funktionen der Windows-API anstatt eine höhere Abstraktionsebene (Klasse TThread) zu wählen?

Edlmann 16. Dez 2010 14:45

AW: Thread in eigene Klasse einbinden?
 
Eben um meinem Thread in eine eigene Klasse zu packen, die wiederum verschiedene Methoden beherrscht...Ich könnte das ganze umstrukturieren, wollte aber erst mal schauen, ob es nicht auch anders geht. Eigentlich finde ich es schöner, eine Funktion zu haben, die eben als Thread läuft, als dafür direkt eine Klasse zu schreiben. Naja, muss ich dann mal schauen.

Danke für deine Hilfe,
Edlmann

Niko 16. Dez 2010 14:52

AW: Thread in eigene Klasse einbinden?
 
Du musst, um einen Zeiger auf eine Klassenmethode zu erhalten, den Klassennamen angeben, nicht den Namen einer Variablen, die das Objekt hält. Also @TPathFinder.Thread statt @MyPather.Thread.

shmia 16. Dez 2010 16:10

AW: Thread in eigene Klasse einbinden?
 
Zitat:

Zitat von Edlmann (Beitrag 1068915)
Eigentlich finde ich es schöner, eine Funktion zu haben, die eben als Thread läuft, als dafür direkt eine Klasse zu schreiben

Ein Thread läuft immer in einem bestimmten Kontext.
Er braucht Eingabedaten und liefert oder befüllt Ausgabedaten.
Wenn man einen Thread nur als Funktion sieht, dann "belügt" man sich selbst, weil der Kontext irgendwo als globale Variablen vorhanden sein muss.

Ganz anderst ist das bei der Klasse TThread.
Wenn man von TThread ableitet, dann sollte man darauf achten alle Eingabe- und Ausgabedaten als Properties anzulegen.
Beispiel:
Delphi-Quellcode:
// Thread-Klasse zur Berechnung der Mandelbrot Menge
TMandelbrotThread = class(TThread)
public
  procedure Execute; override;
   // Eingabeparameter
   property Ziel : TRect; // Bildausschnitt
   property xmin, xmax, ymin, ymax : double; // für Brechnung des Apfelmänchens benötigt
   property ColorTable : TColorTable; // Einfärbeschema

   // Ausgabeobjekt
   property Bitmap:TBitmap;
end;
Bei der Threadklasse siehst du genau, was der Thread an Input braucht und wohin das Ergebnis geht.
Sauber und Objektorientiert! :thumb:
Würde es die Thread-Klasse nicht schon geben, dann müsste man sie erfinden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:19 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