Delphi-PRAXiS
Seite 7 von 8   « Erste     567 8      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Threads und TBitmaps (https://www.delphipraxis.net/181416-threads-und-tbitmaps.html)

Sir Rufo 3. Sep 2014 15:27

AW: Threads und TBitmaps
 
Zitat:

Zitat von TheGroudonx (Beitrag 1270912)
Ich verwende schrittweises Kompilieren immer zur Fehlersuche

Das kann der Delphi-Compiler gar nicht ... :shock:

Es wird komplett kompiliert und dann schrittweise durch den erzeugten Code gelaufen ;)

TheGroudonx 3. Sep 2014 16:20

AW: Threads und TBitmaps
 
Danke für die ganze Hilfe.

Stück für Stück bekomme ich das Endbild nun hin.
Das Locken und Unlocken ist noch die größte Herausforderung, denn wenn auch nur 1 lock oder unlock fehlt geht die ganze Anzeige meistens nichtmehr.

Medium 3. Sep 2014 16:38

AW: Threads und TBitmaps
 
Der Timer da macht mir echte Bauchschmerzen. Probier doch mal bitte folgendes aus:

Delphi-Quellcode:
unit Unit1;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, ExtCtrls, UThread;

type
   TForm1 = class(TForm)
     procedure FormCreate(Sender: TObject);
     procedure ThreadPaint(var msg: TMessage); message WM_THREADPAINT;
   private
   public
     { Public-Deklarationen }
   end;

var
   Form1: TForm1;
   Paintthread : TPaintThread;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Paintthread := TPaintThread.Create(false, self.Handle);
end;

procedure TForm1.ThreadPaint(var msg: TMessage);
begin
  Paintthread.LockBMP;
  try
    self.Canvas.Draw(40, 40, PaintThread.BMP);
  finally
    Paintthread.UnlockBMP;
  end;
end;

end.
Delphi-Quellcode:
unit UThread;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, ComCtrls, StdCtrls, ExtCtrls, SyncObjs;
     
type
  TPaintThread = class(TThread)
  private
    FBMP: TBitmap;
    FBMPCS: TCriticalSection;
    FHandle: THandle;
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: Boolean; aMainformHandle: THandle);
    procedure LockBMP;
    procedure UnlockBMP;
    property BMP: TBitmap read FBMP;
  end;

const
  WM_THREADPAINT = WM_USER + 1234;

implementation

constructor TPaintThread.Create(CreateSuspended: Boolean; aMainformHandle: THandle);
begin
  inherited Create(CreateSuspended);
  FBMPCS := TCriticalSection.Create;
  FBMP := TBitmap.Create;
  FBMP.Width := 300;
  FBMP.Height := 300;
  FHandle := aMainformHandle;
end;

procedure TPaintThread.Execute;
begin
  while not Terminated do
  begin
    LockBMP;
    try
      FBMP.Canvas.MoveTo(Random(300), Random(300));
      FBMP.Canvas.LineTo(Random(300), Random(300));
    finally
      UnlockBMP;
    end;
    PostMessage(FHandle, WM_THREADPAINT, 0, 0);
    sleep(1);
  end;
end;

procedure TPaintThread.LockBMP;
begin
  FBMPCS.Enter;
  FBMP.Canvas.Lock;
end;

procedure TPaintThread.UnlockBMP;
begin
  FMP.Canvas.Unlock;
  FBMPCS.Leave;
end;

end.
Edit:
Zitat:

Das Locken und Unlocken ist noch die größte Herausforderung, denn wenn auch nur 1 lock oder unlock fehlt geht die ganze Anzeige meistens nichtmehr.
Das stimmt, deswegen ist gerade hier die Benutzung von try..finally noch wichtiger als eh schon. Aber das ist eine schöne Fingerübung, denn eigentlich sollte man immer so programmieren, dass alles rund und sauber behandelt wird. Das andere nennt man Frickeln ;)

Sir Rufo 3. Sep 2014 16:42

AW: Threads und TBitmaps
 
Darum nimmt man dafür auch ein
Delphi-Quellcode:
try .. finally
, dann ist das gesichert
Delphi-Quellcode:
SomeCanvas.Lock;
try
  // use SomeCanvas
finally
  SomeCanvas.Unlock;
end;
Irgendwie scheint dir das aber (warum auch immer) zu missfallen ...

Sir Rufo 3. Sep 2014 16:47

AW: Threads und TBitmaps
 
@Medium

Die Eigenschaft
Delphi-Quellcode:
BMP
direkt auf das Feld zu leiten ist natürlich auch Quell des Übels. Da sollte ein Getter den Zugriff regeln.

Und warum willst du mit dem Thread auf genau diese Instanz malen?
Wieso bekommt der Thread dafür nicht eine temporäre Instanz, erstellt das Bitmap und wenn fertig, wird das einfach per Assign an die Bitmap-Instanz gegeben, die von aussen lesbar ist?

Das ist einfach abzusichern und die Blockierung ist minimalst.

EDIT
Und absolut idiotensicher wird der Zugriff, wenn man für den Zugriff eine Methode baut, die den Inhalt an eine Bitmap-Instanz übergibt (falls ein Oberschlaumeier sich einfach die Instanz merkt).
Siehe Beitrag #19

Medium 3. Sep 2014 16:55

AW: Threads und TBitmaps
 
So wie sich der TE hier bisher gegen "zu viel Arbeit" wehrt, wollte ich ihm keine voll ausgestaltete Profi-Lösung mit Queues und allem vorsetzen. Ich sagte "ausprobieren", nicht das genau so benutzen. Es ging mir erstmal nur darum zu sehen, ob das bei ihm auch knallt. Wenn dir mein Code aber so missfällt, kann ich den Beitrag gerne entfernen.

Übrigens: Ein Getter/Setter der lockt bringt da gar nix, weil dann gerade mal das kopieren der Referenz abgesichert würde. Dann schon mindestens mit einer Kopie, aber zum ausprobieren ob ihm der Debugger auch dabei ins Gesicht springt sollte ein "manuelles" Locken über die CS und den Canvas einfach mal genügen. Ich sehe es auch einfach nicht ein, hier fix und fertige Frameworks zu erstellen.

Sir Rufo 3. Sep 2014 17:01

AW: Threads und TBitmaps
 
Ein Getter/Setter der lockt, sichert eben nicht das Kopieren der Referenz ;)

Ok, der Zugriff auf die Referenz ist gesichert, jupp, darum ja auch die Methode aus Beitrag #19 ;)

TheGroudonx 3. Sep 2014 21:45

AW: Threads und TBitmaps
 
Das Programm läuft mittlerweile ganz gut, im Vergleich zu vorher hat es nun 0,1 MB/s Datenträgerauslastung.
Seltsam ist, dass nach ca. 30 sek Laufzeit die Datenträgerauslastung vom System von 5% auf 100% hochfährt und dort bleibt, bis das Programm beendet wird.
Wahrscheinlich wieder ein Thread Fehler, nicht wahr? :roll:
Edit: Entwarnung, zwar passiert das Regelmäßig, doch geht die Auslastung nach kurzer Zeit wieder zurück.

Sir Rufo 3. Sep 2014 22:20

AW: Threads und TBitmaps
 
Was soll man dazu sagen ausser: Wenn es so ist, dann ist es so.

Überleg mal, warum ...

(Kleiner Tip: Wenn überhaupt arbeitet ein zu vernachlässigbar kleiner Kreis an Personen hier im Forum bei der NSA/irgendeinem Geheimdienst oder als Hellseher - wir können also nicht auf deinen Rechner zugreifen oder deine Gedanken lesen. Wie sollen wir also jetzt etwas zu dem Quelltext sagen, der dieses Verhalten verursacht?)

Medium 4. Sep 2014 03:04

AW: Threads und TBitmaps
 
Jetzt geht's auf ein Mal um MB/s auf der Platte. Ich gebs auf. Dieser Thread ist mittlerweile fast schon eine Parodie. Was hat das noch mit Threads oder Bitmaps zu tun? Aber schön, dass es läuft...


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:38 Uhr.
Seite 7 von 8   « Erste     567 8      

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