Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi multithreading funktioniert nicht (https://www.delphipraxis.net/93833-multithreading-funktioniert-nicht.html)

Innos 12. Jun 2007 00:03


multithreading funktioniert nicht
 
Hiii^^

habe ein Programm erstellt, dass bestimmte Pixel solange abfragt, bis eine boolsche bedingung true is also ca. so:

Delphi-Quellcode:
var bool:Boolean;
begin
repeat ..... //Die Pixel sind Tcolor und werden hier immer wieder abgefragt
...
bool:=(Pixel1 = Pixel2) and (Pixel3 = Pixel 4);
until (bool);
wenn ich das starte funktioniert auch alles! nur das programm is während der repeat-schleife nicht ansprechbar... da es aba mehrere procedures durchführen soll is das schlecht!

habe mir gedacht ein Thread würde helfen: hab mich schlau gemacht und thread erstellt... thread funktioniert auch soweit nur bleibt der Hauptthread (VCL) und allgemein das ganze Programm wieder während der repeat-schleife stehn...
funktioniert also der wechsel zwischen den threads nicht oder liegt ein Deadlock vor? synkronisiert hab ich bisher nix^^ habs aba scho oft ausprobiert (ohne erfolg)...

hier mein Thread: alles aus einem Thread-Tutorial http://www.dev-center.de/index.php?c...multithreading

Delphi-Quellcode:
 type
  TBinFertig = procedure(const Content: String) of object;
  TMyOwnThread = class(TThread)
  protected
    MediaPlayer1: TMediaPlayer;
    CB1: TCheckBox;
    CB2: TCheckBox;
    CB3: TCheckBox;
    CB4: TCheckBox;
    procedure Execute; override;
  private
    FBinFertig: TBinFertig;
    procedure SyncBinFertig;

  public
    property BinFertig: TBinFertig read FBinFertig write FBinFertig;
  end;

...
var
  MyOwnThread: TMyOwnThread ;

implementation
{$R *.dfm}

procedure TMyOwnThread.SyncBinFertig;    //weiß damit nix anzufangen, da keine andere porcedure auf zB meine
                                         //Checkbox im Form1 (CB1) zugreift
begin

end;

procedure TMyOwnThread.Execute;

begin
  try

  bool:=false;
      lDC:= GetDC(0);
      if lDC> 0 then
     repeat
        Pixel[1]:= GetPixel(lDC, 554, 138); // hier frag ich einfach die Pixelfarbe von einem Array of TColor ab
       
       if Form1.CB1.Checked=true then   // geht auch... also diese Checkbox zu checken 0o
        bool:=((bool) or x);

        if Form1.CB2.Checked=true then
        bool:=((bool) or y);

        if Form1.CB3.Checked=true then
        bool:=((bool) or z);

        if Form1.CB4.Checked=true then
        bool:=((bool) or a);
                               
          until bool;           //an der endlosschleife bleibt alles hängen es soll aba nur dieser Thread arbeiten NICHT VCL

Form1.MediaPlayer1.Play

  except
    on e: exception do begin
      showmessage('blaa');
    end;
  end;
end;

procedure TSilkroadOnlineTool.Button5Click(Sender: TObject);
var Thread: TMyOwnThread;
begin
 Thread := TMyOwnThread.Create(True);
 Thread.Resume;
  Thread.Suspend;
  Thread.Terminate;
  Thread.Execute;
end;
end.
also habe heute zum ersten ma Thread in diesem zusammenhang gehört!! und hab deswegen kein plan warum es nich klappt ohne, dass der VCL stehn bleibt... neue exe is ne möglichkeit müsste aba dann variablen versenden etc und ich hätte 2 exe-dateien :pale:

also HELFT mir :mrgreen: plz vielen Dank im voraus :thumb:

Matze 12. Jun 2007 05:36

Re: multithreading funktioniert nicht
 
Hallo

Delphi-Quellcode:
if Form1.CB1.Checked=true then
Überprüfe nicht auf = true. Das mag hier zwar gehen, ist jedoch schlecht, sich das so anzugewöhnen. Wieso, steht hier und das ist ganz interessant und sollte man wissen. Mit deinem Problem hat dies allerdings nichts zu tun.

Du greifst jedoch im Thread (Execute) direkt auf die VCL zu beim Ansprechen der CheckBoxen und das ist alles andere als gut. Genauso beim TMediaPlayer. Der Zugriff auf die VCL aus einem Thread sollte generell nur mittels Delphi-Referenz durchsuchenSynchronize erfolgen. Hierzu findest du auch einige Beispiele in der DP. Ich könnte mir vorstellen, dass dies mit deinem Problem zusammenhängt.

Mir persönlich erscheint es auch nicht sinnvoll, in jedem Schleifendurchlauf zu prüfen, welche CheckBox nun gesetzt ist, denn das kostet auch nur Rechenzeit, jedesmal auf die VCL zugreifen zu müssen. Vielleicht wäre es auch sinnvoll, einzulesen, welche CheckBoxen gesetzt sind und den Thread dann mit entsprechenden Parametern zu starten, es sei denn, man soll während des Threads auch eine CheckBox anklicken dürfen und die Änderungen direkt übernommen werden müssen.

Falls das ganze für eine Visualisierung sein soll, tust du dir sicher leichter, wenn du die bass.dll nutzen würdest. Für diese dll gibt es einige Units und Beispiele in der DP, mit denen sich diese sehr einfach ansprechen lässt. Visualisierungen sind damit ein Kinderspiel.
Eine nette Übung ist es natürlich, selbst eine zu schreiben, das ist keine Frage. :)

alzaimar 12. Jun 2007 06:55

Re: multithreading funktioniert nicht
 
Zitat:

Zitat von Innos
Delphi-Quellcode:
 type
  TBinFertig = procedure(const Content: String) of object;
  TMyOwnThread = class(TThread)
  protected
    MediaPlayer1: TMediaPlayer;
    CB1: TCheckBox;
    CB2: TCheckBox;
    CB3: TCheckBox;
    CB4: TCheckBox;
    procedure Execute; override;
...
procedure TMyOwnThread.Execute;
...
       if Form1.CB1.Checked=true then   // geht auch... also diese Checkbox zu checken 0o
...
end;

Wieso deklarierst Du CB1..CB4 im Thread, greifst dann aber auf die CheckBoxen der Form1 zu? Hier ist das zwar gerade noch ok (weil lesend zugegriffen wird), aber ...
Delphi-Quellcode:
Form1.MediaPlayer1.Play
... hier knallts dann endgültig.

Zitat:

Zitat von Innos
Delphi-Quellcode:
procedure TSilkroadOnlineTool.Button5Click(Sender: TObject);
var Thread: TMyOwnThread;
begin
 Thread := TMyOwnThread.Create(True);
 Thread.Resume;
  Thread.Suspend;
  Thread.Terminate;
  Thread.Execute;
end;
end.

Das stößt mir auf: Ich erzeuge einen Thread, wecke ihn kurz auf, lege ihn wieder schlafen, dann sage ich ihm, er soll sich beenden und rufe dann sogar die protected Methode 'Execute' auf. Das kann nicht gut gehen! Du sollst die Execute-Methode nicht anfassen, die geht dich nichts an. Sie ist nicht umsonst als 'protected' deklariert.

Wie startet man einen Thread?
a) Man ruft den Konstruktor mit dem Parameter 'False' auf (der steuert, ob der Thread bei der Geburt schläft oder gleich losbrüllt)
b) Man weckt ihn explizit mit 'Resume' oder 'Suspended := False' auf.

Innos 12. Jun 2007 14:15

Re: multithreading funktioniert nicht
 
JAAA :mrgreen: :mrgreen: es geht^^ DANK an euch !!!

habe den thread mit
Delphi-Quellcode:
 Thread := TMyOwnThread.Create(True);
 Thread.suspended:=false;
aufgerufen und die CheckBoxen und RadioButtons und Mediaplayer komponente nur in Form1 deklariert...
außerdem habe bin ich dann dem deadlock ausgewichen^^ indem ich
am schluss, wo er die mediaplayer komponente abspielen soll (Form1.MediaPlayer1.Play)
synkronisiert habe...

jedenfalls funktioniert jetzt alles^^ THXX

alzaimar 12. Jun 2007 14:27

Re: multithreading funktioniert nicht
 
Wenn Du im Konstruktor keinerlei Vorkehrungen treffen musst, dann kannst du den Thread auch mit 'True' im Konstruktor aufrufen, dann rattert er gleich los.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz