AW: Threads und TBitmaps
Ah, war mir nicht aufgefallen, dass du nur Delphi 7 hast (du könntest das ja in dein Profil eintragen).
Das Prinzip der CriticalSections, Events und Synchronize bleibt aber gleich und kannst du fast 1:1 übernehmen. Wichtig ist einfach, dass alle Zugriffe von aussen entsprechend geschützt erfolgen. Auch die Bitmap, die im Thread erzeugt wird, ist erst nach der Fertigstellung von aussen abrufbar. Solange kann von aussen nur das zuletzt erzeugte Bitmap abgerufen werden.
Delphi-Quellcode:
beinhaltet
System.Generics.Collections
Delphi-Quellcode:
was du anders lösen müsstest, denn Generics sind Delphi 7 nicht bekannt.
TQueue<T>
|
AW: Threads und TBitmaps
Die neue Art sieht so aus:
Aufruf:
Delphi-Quellcode:
Thread:
procedure TForm1.FormCreate(Sender: TObject);
begin Paintthread := TPaintThread.create(false); Paintthread.Image := Image1; end;
Delphi-Quellcode:
Das geht auch sehr gut.
unit UThread;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, ExtCtrls; type Image = TImage; TPaintThread = class(TThread) private Zeichenflaeche: TImage; MyBild : TBitmap; procedure zeichnen; procedure SetImage(const Value: TImage); protected procedure Execute; override; public constructor Create(CreateSuspended: Boolean); property Image: TImage read Zeichenflaeche write SetImage; end; implementation constructor TPaintThread.Create(CreateSuspended: Boolean); begin inherited; MyBild := TBitmap.create; MyBild.LoadFromFile('1.bmp'); end; procedure TPaintThread.Execute; begin While (Terminated = False) do begin Synchronize(Zeichnen); sleep(1); end; end; procedure TPaintThread.Zeichnen; begin Zeichenflaeche.Canvas.Draw(random(50) + 1,random(50) + 1,MyBild); end; procedure TPaintThread.SetImage(const Value: TImage); begin Zeichenflaeche := Value; end; end. Ist das in etwa so wie es richtig ist oder müssen nach wie vor Schutzoptionen wie TCriticalSection darin verwendet werden? |
AW: Threads und TBitmaps
Ähm, das eigentliche Zeichnen erledigt du jetzt im Kontext des Hauptthreads
Delphi-Quellcode:
Damit hast du rein gar nichts gewonnen ... ja, es funktioniert, aber wozu benötigst du dann einen Thread, wenn du es eh wieder im Hauptthread zeichnen lässt.
Synchronize( Zeichnen );
|
AW: Threads und TBitmaps
Zitat:
|
AW: Threads und TBitmaps
In der Tat passiert eine ganze Menge arbeit, das geht aus dem Beispiel jetzt nicht wirklich hervor.
Es sind viele Berechnungen und Zeichnungen, die zu einem Bild zusammengefügt werden, welches dann kopiert werden soll. Da für jedes Bild alles neu berechnet werden muss ist ein thread sinnvoll. Soweit ich das sehe wird nur der Synchronize-Teil von der Hauptform ausgeführt während die Berechnung des Bildes, welches später auf die Hauptform gemalt, threadsicher ist? Oder muss beim Veränderungsvorgang wieder abgesichert werden, obwohl keine Zugriffe von der Hauptform erfolgen (was nicht sehr logisch wäre)? |
AW: Threads und TBitmaps
Zitat:
So sollte Multithreading eben gerade nicht funktionieren. Der Backgroundthread bekommt alle Informationen zum Abarbeiten als Kopie übergeben, bearbeitet das und benachrichtigt, dass er damit fertig ist. Dann kann wer auch immer sich dieses abholen. |
AW: Threads und TBitmaps
Zitat:
|
AW: Threads und TBitmaps
Zitat:
|
AW: Threads und TBitmaps
Zitat:
Delphi-Quellcode:
..auf eine thread-interne ressource gezeichnet wird, CalcABitmap() benötigt entspr. Zeit und - wenn fertig - wird zum mainthread context gewechselt ... und da kann das bild ja abholen wer will ... in dem beispiel wirds halt in ein TImage geblittet und somit am schirm ausgegeben ...
procedure TPaintThread.Execute;
begin While (Terminated = False) do begin CalcABitmap(MyBild); // komplexe zeichenoperation... Synchronize(Zeichnen); sleep(1); end; end; |
AW: Threads und TBitmaps
Was mich nur noch verwundert ist, dass wenn ich den Thread durchsteppe, nach wie vor access-violations bzw auch einmal eine eexternalexception auftreten, während Threadeigene Bitmaps bearbeitet werden, auf die nicht von ausserhalb des Threads zugegriffen wird, welche auch 100% existieren. Dabei variiert das Tempo, in dem man zur nächsten Codezeile springen kann, stark, was normalerweise nicht passiert.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13: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