AW: Threads und TBitmaps
Lockst du deinen MyBild.Canvas auch korrekt?
Delphi-Quellcode:
procedure TPaintThread.CalcABitmap(const MyBild: TBitmap);
begin MyBild.Lock; try .. malen bis der bär kommt .. finally MyBild.Unlock; end; end; |
AW: Threads und TBitmaps
Wie gesagt wenn ich diese Art von locken verwende (MyBild.Canvas.lock) kommt es zu Fehlermeldungen.
Lasse ich es weg funktioniert es in der Regel. Mein Problem ist jedoch, dass es bei meinem Beispielprojekt funktioniert, nicht aber bei meinem größeren Projekt. Ich versuce gerade herauszufinden, wo der Unterschied liegt. :? |
AW: Threads und TBitmaps
Na toll,
habe gerad herausgefunden, dass die Zeichenprozedur des Threads aufhört richtig zu arbeiten, kurz nachdem man mit der Maus über das TImage der Form fährt ._. |
AW: Threads und TBitmaps
Liste der Anhänge anzeigen (Anzahl: 2)
Hier ist die Beispielunit, ihr könnt da ja mal testen ob es bei euch auch aufhört zu arbeiten.
Edit: Ausversehen falsche Datei hochgeladen, stimmt jetzt aber... |
AW: Threads und TBitmaps
Die Art zu Locken verriegelt auch über eine globale CriticalSection (das gewählte Canvas ist hier eh "wurscht"), was heißt daß sich Deine Threads gegenseitig blockieren.
Wenn Du eine Möglichkeit sucht ohne Canvas in mehreren Threads parallel zu arbeiten um am Schluss das ganze synchronisiert auf die Oberfläche zu bringen könntest Du Dich mit GDI+ beschäftigen. Hier funktioniert es auch ohne Canvas/HDC mit GdipGetImageGraphicsContext/GdipCreateBitmapFromScan0. Da Bilsen erst ab D2009 funktioniert und progdigy nicht mehr existiert könntest Du das benötigte bei http://lummie.co.uk/gdi-controls-for-delphi/ finden. |
AW: Threads und TBitmaps
...wie gesagt wenn du korrekt lockst/unlockst geht das (zumindestens bei mir unter xe5) problemlos...
Delphi-Quellcode:
procedure TPaintThread.Execute;
begin While (Terminated = False) do begin MyBild.Canvas.lock; Original.Canvas.Lock; try MyBild.Width := random(500) + 500; MyBild.Height := random(500) + 500; MyBild.Canvas.Draw(random(25) + 1, random(25) + 1, Original); MyBild.Canvas.Rectangle(random(25) + 1, random(25) + 1, random(50) + 25, random(50) + 25); finally MyBild.Canvas.unlock; Original.Canvas.Unlock; end; Synchronize(Zeichnen); end; end; |
AW: Threads und TBitmaps
Zu Bummis Vorschlag: Viel zu kompliziert. Das geht wunderbar mit Delphis ganz normalem TBitmap. Man sollte eben wie schon zuvor erwähnt, in Threads immer nur mit Kopien arbeiten, oder zumindest ein wasserdichtes Synchronisationskonzept haben. Ich habe schon zig Programme geschrieben, die auf diese Weise aufwändige Bilder parallel zeichnen. Dem TE jetzt zusätzlich zum Thema Threads auch noch mit GDI+ zu kommen, halte ich für viel zu viel auf ein Mal. (Zumal GDI+ praktisch schon totgesagt ist, und somit nicht mal viel für die Zukunft gelernt ist.)
|
AW: Threads und TBitmaps
Ups, habe vergessen die 2te Bitmap (original) mit zu locken/unlocken...
Das hat scheinbar einen großen Effekt gehabt. |
AW: Threads und TBitmaps
Do loops endlos
Delphi-Quellcode:
zudem erzeugst Du das Bild im Kontext des Hauptthreads (Create) , erst im Execute bist Du im Threadkontext.
While (Terminated = False) do
begin |
AW: Threads und TBitmaps
@Medium ich denke es hängt von den Anforderungen ab, mit Synchronisierung egal ob Canvas.Lock oder eigenen CriticalSections wird es bei mehreren fast so langsam dass man es auch im Hauptkontext laufen lassen könnte und ohne kommt es definitiv zu Fehlern, was leicht zu zeigen ist:
Delphi-Quellcode:
unit Unit2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm2 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; TTestThread=Class(TThread) private FFn:String; public Constructor Create(fn:String);overload; Procedure Execute;override; End; var Form2: TForm2; implementation {$R *.dfm} { TTestThread } constructor TTestThread.Create(fn: String); begin inherited Create(false); FFn := fn; end; procedure TTestThread.Execute; var bmp :TBitmap; i:Integer; begin inherited; bmp :=TBitmap.Create; bmp.Width := 100; bmp.Height := 100; bmp.Canvas.Pen.Color := clBlue; for I := 0 to 100 do begin bmp.Canvas.MoveTo(0,0); bmp.Canvas.LineTo(100,i); end; bmp.SaveToFile('C:\temp\test\' + Ffn ); bmp.Free; end; procedure TForm2.Button1Click(Sender: TObject); var i:Integer; begin for I := 0 to 20 do TTestThread.Create(IntToStr(i)+'.bmp'); end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:29 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