AW: Threads und TBitmaps
Was für Fehler kommen da? Bist du sicher, dass die nicht damit zusammen hängen, dass du da reichlich Speicherlecks produzierst? Oder mit dem Abspeichern?
|
AW: Threads und TBitmaps
Liste der Anhänge anzeigen (Anzahl: 4)
@Medium danke für den Hinweis auf das fehlende Free, aber damit hat es nicht zu tun, wenn du die Bitmaps anschaust siehst Du was ich meine.
|
AW: Threads und TBitmaps
Also auch das Beispiel geht bei mir einwandfrei...
Delphi-Quellcode:
mit 200 Threads probiert (auch wenn des sinnbefreit ist..)
procedure TTestThread.Execute;
var bmp :TBitmap; i:Integer; begin bmp :=TBitmap.Create; bmp.Canvas.Lock; 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; |
AW: Threads und TBitmaps
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Diese findet allerdings nicht im Threadablauf, sondern im Prozess der Hauptform statt, während das Bild per Synchronize gezeichnet wird. Diese EAccessViolation findet sogar dann statt, wenn man den Code so abändert:
Delphi-Quellcode:
Das bedeutet, dass allein das Aufrufen der (leeren) Synchronize-Methode einen EAccess-Error hervorruft, zumal nichts anderes der Auslöser sein kann.
procedure TPaintThread.Execute;
begin While (Terminated = False) do begin try Synchronize(Zeichnen); finally end; sleep(1); end; end; procedure TPaintThread.Zeichnen; begin // end; Versteht ihr, was da schief läuft? (Der Fehler kommt oft nach einigen Sekunden, manchmal aber auch garnicht) |
AW: Threads und TBitmaps
Ich habe das jetzt nochmal erweitert getestet und festgestellt, dass es nicht an der Snchronize-Methode liegt.
JEDE Kommunikation von MainForm zu Thread per Prozedur kann (nach 10-100 Aufrufen im Mittel) diese Access-Violation beim Durchsteppen auslösen. Was ich mich jetzt frage ist: -Wieso kommt es dazu? -Lässt es sich vermeiden? (Vermutlich nicht) -Hat die Fehlermeldung beim Durchsteppen auch Relevanz beim normalen Ablauf des Programms? :? |
AW: Threads und TBitmaps
Also wir müssen uns hier auf eine korrekte Sprache einigen, denn sonst weiß keiner was wirklich gemeint ist. Beim Thema Multithreading ist das einfach unerlässlich.
Es kommt immer auf den Thread-Kontext an. Wenn du also bei irgendetwas im Bereich Multithreading Probleme hast, dann ist es sehr wichtig, dass du dabei den Thread-Kontext mit angibst, und nicht welche Form da was aufruft. Auch die Methode einer Form kann in jedem beliebigen Thread-Kontext aufgerufen werden, niemand hindert dich daran. Greifst du in irgendeinem Thread-Kontext <> MainThread-Kontext auf die VCL zu, dann kann es rummsen - das ist ja das Gemeine, es rummst nicht immer ;) Den aktuellen Thread-Kontext fragt man ganz einfach mit
Delphi-Quellcode:
ab (bei Delphi 7 war das
TThread.CurrentThread.ThreadID
Delphi-Quellcode:
oder so) und den MainThread-Kontext mit
GetCurrentThreadID
Delphi-Quellcode:
. Sind die beiden Werte unterschiedlich, dann ist man eben nicht im MainThread-Kontext.
MainThreadID
|
AW: Threads und TBitmaps
Zitat:
Meines Wissens führt der Thread alles selbstständig aus, was über seine Routine Execute verbunden ist und kein Synchronize ist. Jedenfalls ruft der Hauptprozess eine leere Methode des Threads auf, was zu einem Fehler führt. (siehe oben!) |
AW: Threads und TBitmaps
Zitat:
Also wer ruft jetzt in welchem Thread-Kontext was auf?
Delphi-Quellcode:
PS
procedure TPaintThread.Execute;
begin While (Terminated = False) do begin try Synchronize( Zeichnen ); finally end; sleep(1); end; end; procedure TPaintThread.Zeichnen; begin // end; Wenn die
Delphi-Quellcode:
Methode im MainThread-Kontext aufgerufen wird (weil du diese Methode direkt aufrufst), dann ist es kein Wunder, dass du da Probleme bekommst, denn vom MainThread-Kontext aus
TPaintThred.Execute
Delphi-Quellcode:
aufrufst, dann kann das zu Problemen führen, wie es auch in der Dokumentation angegeben ist.
Synchronize
|
AW: Threads und TBitmaps
Der normale Mainthread-Context erstellt den Thread(TThread)-von da aus läuft alles von selbst weiter.
Der Thread(TThread) ist in einer separaten Unit. Er(Der Thread) arbeitet seine Execute Methode ab. Dabei ruft er die Synchronize(Zeichnen) Prozedur auf, durch welche der Mainthread-Context die Zeichen-Routine ausführt. Dies führt nach Wiederholungen beim Durchsteppen zu einem EAccess-Violation Fehler. Dieser Fehler passiert, da die Zeichenmethode per Synchronize aufgerufen wird, im Mainthread-Context, wobei die Abbruchstelle am Ende der Zeichenroutine(leer) in der Thread-Unit ist. |
AW: Threads und TBitmaps
Kann ich so nicht nachvollziehen, läuft wie erwartet
EDIT Überwachung des Thread-Kontexts
Delphi-Quellcode:
unit PaintThread;
interface uses Classes; type TPaintThread = class( TThread ) private procedure Zeichnen; protected procedure Execute; override; end; implementation uses SysUtils, Windows; { TPaintThread } procedure TPaintThread.Execute; begin if MainThreadID = GetCurrentThreadId then raise Exception.Create( 'Upps, ich darf nicht im MainThread-Kontext sein!' ); inherited; while not Terminated do begin Synchronize( Zeichnen ); Sleep( 1 ); end; end; procedure TPaintThread.Zeichnen; begin if MainThreadID <> GetCurrentThreadId then raise Exception.Create( 'Upps, ich bin nicht im MainThread-Kontext!' ); end; end.
Delphi-Quellcode:
unit FormMain;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, PaintThread; type TForm1 = class( TForm ) private FPaintThread : TPaintThread; public procedure AfterConstruction; override; procedure BeforeDestruction; override; end; var Form1 : TForm1; implementation {$R *.dfm} { TForm1 } procedure TForm1.AfterConstruction; begin inherited; FPaintThread := TPaintThread.Create( False ); end; procedure TForm1.BeforeDestruction; begin inherited; FPaintThread.Free; end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:27 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