![]() |
AW: TBitmap ist NICHT threadsave
Zitat:
Alle GUI-Ressourcen von Windows sind nur im erzeugenden Thread gültig. D.h. wenn du dein Bitmap nur in einem Thread erzeugst, bearbeitest und freigibst ist alles gut. Damit hat auch die VCL kein Problem da hier keine weiteren Abhängigkeiten zu Formular, Screen und Co. existiert. |
AW: TBitmap ist NICHT threadsave
Zitat:
|
AW: TBitmap ist NICHT threadsave
Kämpf dich doch mal durch den Code von TBitmap,
also vorallem wo das Canvas her kommt und speziell die darin vorhandenen TPen oder TBrush. Da landet man z.B. beim TResourceManager, der die Resourcen threadabhängig verwaltet. |
AW: TBitmap ist NICHT threadsave
Hallo Zusammen,
OK, ... scheint also doch immer noch ein kleines Problem mit sehr unterschiedlichen Erfahrungen zu sein. Wie ich schon sagte, ist mir seit den Anfängen von Delphi klar, dass vieles in der VCL bzw. in FMX NICHT threadsave ist. Und es ist auch richtig, dass man grundsätzlich unterstellen sollte, dass alles, was man benutzt, vielleicht NICHT threadsave ist. Ich hatte aber gehofft, dass ich in einem Thread eine FMX-Bitmap mit Map öffnen kann und dann selber Pixel lesen und/oder manipulieren kann. Aber selbst das geht eben in 1..10 % der Fälle schief und man merkt es nicht, da evtl. nur einige Pixel falsch sind. Das hatte ich einfach nicht erwartet. Wohlgemerkt, ein Synchronize über den Bmp-Methoden im Thread und alles ist wieder gut. Deshalb gehe ich auch davon aus, dass mein Test OK ist, was man natürlich auch noch hinterfragen kann. Wie Harry vorgeschlagen hat, werde ich deshalb, wenn ich Zeit habe, meinen Test aus meinem Framework separieren und hier hochladen. Das kann aber etwas dauern, da ich wie 'immer' unter Zeitmangel leide. |
AW: TBitmap ist NICHT threadsave
Es gibt einen Unterschied zwischen threadsafe und threadaffin. Die meisten Klassen sind nicht threadsafe aber - gottlob - auch nicht threadaffin.
Delphi-Quellcode:
gehört eindeutig zur Kategorie ganz blöd.
TBitmap
Wenn jemand so etwas in einem Thread verwendet und keine Probleme damit hat, dann jeden Abend das in das Nachtgebet mit einschliessen und weiter hoffen. Es ist keine zugesicherte Eigenschaft und läuft wohl eher durch Zufall (oder man hat sich irgendwo durch die Hintertür eine Synchronisation eingefangen). Anyway, empfehlen würde ich es nicht und darauf bauen erst recht nicht. Aber eine Hummel kann eigentlich auch nicht fliegen und tut es trotzdem, weil ihr die Physik und Aerodynamik fremd und sowas von egal sind. :stupid: |
AW: TBitmap ist NICHT threadsave
Zitat:
Zitat:
Wenn man nur das BMP im Speicher anlegt und über Scanline auf die Pixel zugreift ist es im Thread machbar, sobald ein Canvas oder was anderes in Spiel kommt ist es MainThread affin ? Ich halte es so das ich nur im Mainthread drauf zugreife, weil mir diese Aussagen auch nicht 100% sicher sind. Rollo |
AW: TBitmap ist NICHT threadsave
@Rollo62
Es gibt keine konkrete Aussage darüber, was man von
Delphi-Quellcode:
gefahrlos im Thread verwenden kann und was nicht - es hat beim Klassendesign keinen interessiert.
TBitmap
Zugesichert wird nur das korrekte Verhalten im MainThread. Den Rest muss man sich durch SourceCode-Wälzen zusammensuchen. Einfaches Ausprobieren reicht da leider nicht aus, denn eine race condition macht sich meist erst dann bemerkbar, wenn man gerade nicht hinschaut (Murphys Law) |
AW: TBitmap ist NICHT threadsave
Kategorie "ganz blöd" kannte ich noch nicht, aber sofort in mein Repertoire aufgenommen. :-D
Wenn es unbedingt parallel sein muss, geht es so: 1) MainThread: Kopie einer Bmp in ein allociertes Memory, das geht sau schnell, wenn man das Memory genau wie die Bmp organisiert. 2) SomeThread: Manipulieren des Memories, vielleicht den alten Brasenham-Algorithmus wieder aus dem Keller holen. Aber bitte an den Rändern richtig clippen. Sonst gibt es Überraschungen. 3) MainThread: Kopie des Memories zurück in die Bmp, das geht wieder schnell. So mache ich z.B. 3D - Rotationen (ohne die 3D-Engine vom System) mit mehreren Threads gleichzeitig. Das funktioniert einwandfrei. Man muss nur schmerzfrei bleiben, bis alles läuft. Für viele Aufgaben, die man hat, kann man ja eine eigene TcMemBmp-Class bauen. Bilder abdunkeln, aufhellen, oder sogar Linien zeichnen ist ja trivial. Benötigt man aber den gesamten Comfort des Canvas oder will rendern, sollte man wohl besser im MainThread bleiben. Wahrscheinlich könnte man auch eine dll schreiben, die nichts anderes macht, als Bitmaps zeichnen. Aber das ist irgendwie auch "ganz blöd". |
AW: TBitmap ist NICHT threadsave
Vielleicht kann man aber folgendes machen:
1) MainThread: Bmp.map aufrufen. 2) SomeThread: Direktes Manipulieren der TBitmapData.Data. 3) MainThread: Bmp.unmap aufrufen. Das müsste ja OK sein, solange der MainThread die Bmp nicht anrührt, bis die Threads fertig sind. Oder? |
AW: TBitmap ist NICHT threadsave
Zitat:
Wenn der Mainthread mit einem blanken Zeiger auf den Daten herumholzen kann, sollte das der Hilfsthread auch können. Denke aber daran, dass der Ablauf dann richtig synchronisiert werden muss. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:43 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