AW: Threads und TBitmaps
Zitat:
Es wird komplett kompiliert und dann schrittweise durch den erzeugten Code gelaufen ;) |
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. |
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:
Edit:
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. Zitat:
|
AW: Threads und TBitmaps
Darum nimmt man dafür auch ein
Delphi-Quellcode:
, dann ist das gesichert
try .. finally
Delphi-Quellcode:
Irgendwie scheint dir das aber (warum auch immer) zu missfallen ...
SomeCanvas.Lock;
try // use SomeCanvas finally SomeCanvas.Unlock; end; |
AW: Threads und TBitmaps
@Medium
Die Eigenschaft
Delphi-Quellcode:
direkt auf das Feld zu leiten ist natürlich auch Quell des Übels. Da sollte ein Getter den Zugriff regeln.
BMP
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 |
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. |
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 ;) |
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. |
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?) |
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. |
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