![]() |
Problem mit Threading / Störung durch Mausbewegungen
Hallo Leute,
nachdem ich seit geraumer Zeit hier angemeldet und fleissiger Leser bin habe ich nun ein Problem, welches ich hier zur Diskussion stellen möchte und von dem ich hoffe, dass jemand eine gute Idee hat. Die Software an der ich arbeite muss u.U. eine ganze Reihe von Bildern laden , welche im PCX-Format vorliegen und von einer DLL in eine interne Speicherstruktur geschrieben werden. Anschliessend wird mittels der RGB-Funktion das Ganze in ein TBitMap geschrieben. Das Ganze braucht je nach Anzahl der Bilder relativ lang, was zu der Überlegung führte diese Sache in einen Hintergrundthread zu verfrachten - die Datenstrukturen stehen momentan nicht zur Diskussion. Gesagt getan - das Ganze scheint auch zu funktionieren, allerdings bereitet mir eines noch Kopfzerbrechen. Wenn während dieses Lade/Konvertierungsvorganges z.B. die Maus bewegt wird erscheint beim Öffnen der Bilder eine Fehlermeldung mit "EOutOfRessources" und einem völlig bescheuerten Hinweis :wiejetzt: auf nicht existierende Dateien die von Canvas beim Zeichnen in das TImage (in das die Bitmap gehört) ausgelöst wird. :gruebel: Das wird aber vermutlich "Zufall" sein, dass es gerade dort knallt. Ich weiss wohl, dass TBitmap in Bezug auf Threads "böse" ist - aber kann das daher kommen? Es wird nur ein Hintergrund-Thread erzeugt, der ein bisschen Kleinzeug, das Laden der PCX-Dateien über die DLL, sowie die Konvertierung macht und anschliessend endet. Hätte ich gegebenenfalls eine Möglichkeit da minimalinversiv was zu ändern, sprich ohne das ganze Programm umzubauen? Den Thread starte ich folgendermaßen:
Delphi-Quellcode:
ThreadInfo ist ein gepackter record in dem ich einige Daten übergebe, die der Thread benötigt, u.a. auch das Objekt in dem die ganzen Bilddaten abgelegt werden.
BeginThread(nil, 0, @LoadPCXData, @ThreadInfo, 0, ThreadID)
Es wäre mir echt eine grosse Hilfe, wenn da jemand eine gute Idee hätte... Besonders ärgerlich ist, dass die Grundfunktionalität ja OK ist, aber eben durch äussere Einflüsse dermassen durcheinander gebracht wird. Danke im Voraus, Carsten |
Re: Problem mit Threading / Störung durch Mausbewegungen
Wenn die VCL im Spiel ist, IMMER synchronize verwenden.
Das kommt sehr wahrscheinlich von dem TBitmap, denn das ist auch aus der VCL. Es passiert so: Wenn das Programm läuft, ohne dass jemand was macht (Maus bewegen, oder so), dann klappt alles. Kommt nun aber dummerweise eine Mausaktion (oder sonst was dazu), dann wird eine Nachricht von Windows an das Programm geschickt, dass es sich gefälligst neu zeichnen soll. Nun werden alle betroffenen Komponenten neu gezeichnet und es knallt. Der Thread will in das TImage schreiben, dieses zeichnet sich aber gerade neu und steht somit nicht zur Verfügung. Also, entweder synchronize oder vom Thread eine Message an das hauptprogramm schicken, dass das TImage aktualisiert werden soll. Zu synchronize findest Du jede Menge Diskussionen hier. Oder Du bemühst die Delphi-Hilfe. |
Re: Problem mit Threading / Störung durch Mausbewegungen
Auch das TBitmap ausserhalb des Threads erstellen, also synchroniziert, da die VCL viele Listenklassen hält mit den GDI Objekten und die Zugriffe auf diese Listen sind nicht synchronisiert.
|
Re: Problem mit Threading / Störung durch Mausbewegungen
Hallo und danke schonmal für die Antworten, ich muss da aber wohl noch etwas präzisieren... ;)
Zitat:
Das TBitmap ist in einer Klasse untergebracht die nur zur Datenhaltung dient, aber in keinerlei sichtbare Elemente (kein Formular) hat. Es wird auch nicht im Thread erzeugt, sondern ist Bestandteil dieser Klasse und wird schon beim Programmstart erzeugt. Genaugenommen handelt es sich dabei um ein "array of TBitmap", welches dann von einer Schleife n-fach im Thread (je nach Anzahl der Bilder) durchlaufen und gefüllt wird. Wird dann ein Bild über das TTreeView geöffnet wird es per Assign in einem lokalen TBitmap des Formulares zur Verfügung gestellt in dem damit gearbeitet wird. Dieses TBitmap wird dann wieder Assigned auf das TImage. :pale: |
Re: Problem mit Threading / Störung durch Mausbewegungen
Zitat:
|
Re: Problem mit Threading / Störung durch Mausbewegungen
Nein. Während der Thread läuft ändert sich nix an dem Array und den Bitmap-Instanzen. Diese werden u.U. später nochmal verändert - allerdings brauche ich für ein einzelnes Bild das u.U. irgendwann mal hinzukommt keinen extra Thread.
Der ist nur um beim Laden eines Projektes, wo ja häufig mehrere Bilder bearbeitet werden die Wartezeit zu Verkürzen bis man mit dem Programm arbeiten kann. |
Re: Problem mit Threading / Störung durch Mausbewegungen
Egal was sonst noch querschlagen kann, aber das TBitmap besitzt ein Canvas. Und ein TCanvas benutzt globale Variablen und das ist nicht threadsicher.
|
Re: Problem mit Threading / Störung durch Mausbewegungen
OK. Ich hab das Ganze nochmal umgebaut... Die Ladefunktion der DLL wird nun im Thread ausgeführt und die Konvertierung auf TBitMap mache ich erst wenn jemand das Bild effektiv benötigt, sprich es öffnet.
Somit ist das Ziel erreicht das Laden von Projekten zu beschleunigen, und die Zeit die es beim Öffnen eines einzelnen Bildes für die Umrechung braucht ist zu vernachlässigen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:01 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