![]() |
Delphi-Version: XE5
Thread mit komischem Verhalten
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ich versuche, die Kompression von Bitmaps (nach PNG bzw. JPG) in einen Thread auszulagern. Den entsprechenden Code habe ich angehängt. Das komische daran ist, dass die Ausgabe der fertigen Dateien perfekt funktioniert, wenn ich mit
Delphi-Quellcode:
bestimmten Code mit ausführen lassen. Es handelt sich dabei um eine "LOG-Datei", die mir die Dateinamen der Quelldateien ausgibt. Das ganze realisiere ich über eine
{$DEFINE DebugUnit}
Delphi-Quellcode:
.
TStingList
Wird dieser Code nicht mit compiliert, funktioniert es plötzlich nicht mehr - also es werden keine Ausgabe-Dateien in Form von PNG bzw. JPG. Im Moment bin ich sehr ratlos und würde mich freuen, wenn mir jemand sagen kann, woran es liegt. Gruß, Alex |
AW: Thread mit komischem Verhalten
Da kann ich dir helfen:
Jedes Mal, wenn du Delphi, Bitmap und Thread in einem Satz sagst, streichst du diesen Satz (bis auf Weiteres) wieder aus deinem Gedächtnis :stupid: Du kannst fast alles im Thread machen, aber Bitmaps (VCL/FMX) gehen nicht! Marco Cantù In general, bitmap operations in background threads have never been allowed, although they do occasionally work. ![]() |
AW: Thread mit komischem Verhalten [Bild-Kompression]
Zitat:
Allerdings ist die Umwandlung von zig BMP in JPG und insbesondere von PNG nicht ein einem Hauptprogramm für den Benutzer erträglich machbar. Da käme mir einzig die Idee, ein weiteres kleine Programm zu schreiben, was im Hintergrund läuft und dessen Resourcen vom BS zugeteilt werden. Ich fände das aber keine schöne Lösung. Wenn ich die Antwort sklavisch lese, gehen also "nur" VCL/FMX nicht; GDI+ evtl. dagegen schon. Letzteres ist aber so kompliziert, dass ich davon schon seit langem wieder die Finger gelassen habe. Wie macht man es dann möglichst einfach und für Laien wie mich handhabbar? |
AW: Thread mit komischem Verhalten
Sehe gerade, dass du wohl ein VCL-Programm schreibst.
Dann kannst du Bitmap32 von ![]() |
AW: Thread mit komischem Verhalten
Nur um Klarheit zu bekommen. Man kann kein Bitmap-Objekt in einem Thread außer dem Hauptthread erstellen?
|
AW: Thread mit komischem Verhalten
Bisher, bei den Dingen die ich bisher so in Threads gemacht habe, und Bitmaps waren dabei, war es eigentlich immer so, dass Ressourcen die ich in einem Thread-Kontext nutzen will, diese auch dort erzeugt werden müssen. Das heisst insbesondere bei der Delphi-RTL-Implementierung "TThread": Etwas, was im Konstruktor erzeugt wird, ist NICHT im Thread-Kontext, sonderm im Hauptthread erzeugt. Nur Dinge die in der Execute-Methode erstellt werden sind auch wirklich im Thread-Kontext, und gerade bei so manchen Systemressourcen, und insbesondere bei GDI-Zeug scheint das recht wichtig zu sein. (Ich habe mir den Code jetzt nicht angeschaut um zu wissen ob das hier zutrifft, ich sollte eigentlich schleunigst ins Bett.) Und so lange man ein Bitmap in Thread-Kontext im selben Kontext auf die Platte schreibt, und nicht etwa noch fix auf einem Formular darstellen will, muss man sich imho nichtmals um irgendwelche Synchronisierungen kümmern.
Meine Erfahrungen decken sich hier nicht mit Marcos Aussage. |
AW: Thread mit komischem Verhalten
Zitat:
Aus diesen Gründe läuft es im Prinzip so, dass das Hauptprogramm die Bitmaps als Dateien im Temp-Verzeichnis ablegt. Dem Thread übergebe ich jeweils nur den Dateinamen als String. In
Delphi-Quellcode:
erzeuge ich dann in jeder Schleife ein Bitmap. Verkürzt sieht das so aus:
Execute
Delphi-Quellcode:
Procedure TWorkThread.Execute;
Var I : Integer; aBMP : TBitmap; Begin While (Not Terminted) Do Begin For I:=0 To Pred(Length(fArray)) Do Begin If (Not fArray[I].Done) Then Begin fArray[I].Done:= True; aBMP:= TBitmap.Create; Try aBMP.LoadFromFile(fArray[I].FileName); With TPngImage.Create Do Try Assign(aBMP); // Bild übernehmen SaveToFile(fArray[I].DestName); Finally Free; End; Finally aBMP.Free; End; End; End; End; End; |
AW: Thread mit komischem Verhalten
Danke nochmal für die zahlreichen Antworten.
Zitat:
|
AW: Thread mit komischem Verhalten
@Medium
Das Problem hängt mit der Koppelung zwischen
Delphi-Quellcode:
und
TBitmap
Delphi-Quellcode:
zusammen. Der Canvas selber wird allerdings lazy erstellt (was manchmal selbst zu seltsamen Ergebnissen führt, die sich durch ein einfaches
TCanvas
Delphi-Quellcode:
lösen können.
myBitmap.Canvas;
Delphi-Quellcode:
ist nicht thread-safe und kann auch nicht thread-safe verwendet werden (intern gibt es da globale Abhängigkeiten) und darum ist
TCanvas
Delphi-Quellcode:
nicht thread-safe.
TBitmap
Was allerdings nicht heißt, dass es keine Anwendungen gibt, die ein
Delphi-Quellcode:
in einem Thread verwursten und es sogar funktioniert. Die haben einfach nur Glück wenn es funktioniert. Diese "race conditions" tauchen auf, wenn sie wollen und nicht wenn man es von ihnen erwartet ;)
TBitmap
|
AW: Thread mit komischem Verhalten
Zitat:
Zitat:
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:58 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